まず、もちろん、あなたは物事を指定する必要がありますあなたよりも少し厳しいです。 持っています。例えば、"[ 11 12 13; 21 22; 31 32 33 ]"
のようなもので何をすればいいですか?例えば、欠損値の場合は0.0
を挿入するか、 failbit
と設定しますか?
それ以外では、入力を収集するためにstd::vector
を使用すると、 ビットが簡単になります。例えば次のようなものは、:もちろん
template< typename T >
char getRow(std::istream& source, std::vector<T>& dest)
{
dest.clear();
char separator;
source >> separator;
while (source && separator != ';' && separator != ']') {
source.unget();
T tmp;
source >> tmp;
if (source) {
dest.push_back(tmp);
source >> separator;
}
}
if (source && dest.empty()) {
dest.setstate(std::ios_base::failbit);
}
return source ? separator : '\0';
}
template< typename T >
char getFirstRow(std::istream& source,
std::vector<std::vector<T> >& dest)
{
dest.clear();
std::vector<T> row;
char separator = getRow(source, row);
if (source) {
if (row.empty()) {
dest.setstate(std::ios_base::failbit);
} else {
dest.push_back(row);
}
}
return source ? separator : '\0';
}
template< typename T >
char getFollowingRow(std::istream& source,
std::vector<std::vector<T> >& dest)
{
std::vector<T> row;
char separator = getRow(source, row);
if (source) {
if (row.size() != dest.front().size()) {
dest.setstate(std::ios_base::failbit) ;
} else {
dest.push_back(row);
}
}
return source ? separator : '\0';
}
template< typename T >
std::istream&
operator>>(std::istream& source, Matrix<T>& dest)
{
char separator;
source >> separator;
if (separator != '[') {
source.setstate(std::ios_base::failbit);
} else {
std::vector<std::vector<T> > results;
separator = getFirstRow(source, results);
while (separator == ';') {
separator = getFollowingRow(source, results);
}
if (separator != ']') {
source.setstate(std::ios_base::failbit);
}
if (source) {
dest.assign(results);
}
}
return source;
}
、これはMatrix<T>::assign
機能は寸法を設定する できなければならないことを意味します。また、Matrix<T>
には、デフォルトの コンストラクタが必要です。これはおそらく実際の構築を「延期」して Matrix<T>::assign
になります。
また、iostreamsでのエラー報告については、制限付きの可能性がある程度制限されています( )。特に、 のような入力を区別するには、"[11 12 13; 21"
のような入力と何も指定しないでください(ファイルの条件の真の末尾 )。しかし、"21"
の後に区切り記号を読み取ろうとするとeofbit
と設定され、それについては何もできません。 (実際には、 は、我々は場合は、それを設定し、std::ios_base::xalloc()
を使用して、 を新しいステータス・ワードを作成することができ、そして場合にのみ、開始時'['
の読み取りは eofbit
セットで失敗します。しかし、これは をチェックする非常にunstandard方法を必要としますクライアントコードのエラーのために、メンテナンスの問題の無限ストリーム が作成されます。)
最後に、2つのメタコメント:これが複雑に見える場合は...そうです。入力 は、さまざまなエラー のすべてをチェックする必要があるため、ほとんどの場合複雑です。そして第二に、それぞれの操作(並べ替え)を簡単に保つために、関数の使用に注意してください。 それはほとんど常に貧しいプログラミングは、例えば、 Matrix
のようなものに数学的アルゴリズムを適用した場合を除き、 関数内のネストされたループを、持っている だこの—のようなものを打破しないように、初心者の頻繁 間違いです。この場合、解析は数学的なアルゴリズムではなく、 を使用して、各行の処理を全体的な処理から切り離したいことがあります。この場合は のように、最初の行の処理を別の行と区別すると便利です。エラーケースが異なるためです。 (最初の行 は、0より大きい任意の長さを有することができ、後行が前の行と同じ長さ を有していなければならない。)
私はこのエラーを取得:変数を「STD :: istringstream strstm」は初期化が、不完全型 – shizzle
を有します@ shizzle: '#include'が必要です。 –