2011-12-22 15 views
0

私は私のオペレータといくつかの問題を抱えている>>C++のIStream演算子>>

istream& operator>> (istream& is, Matrix& M) { 

    char first; 

    is>>first; 


    for(int i = 0;i<M.rows();i++) { 

     for(int j = 0;j<M.cols();j++) { 

      is>>M[i][j]; 
      cout<<M[i][j]; 

     } 

     is>>first; 

    } 

    return is; 
} 

私は、彼らが依存しないようにループのために変更したいので、私はIStreamの演算子の大きさにしたいです送信された行列は、サイズ1の行列とストリーム[1 2 3 4; 4 5 6 7; 1 2 3 4]を送信した後、サイズ(3 * 4)の新しい行列を構築する必要があります。行列Mに代入演算子を割り当てることができます。

つまり、ストリームの形式は"[ 1 2 3; 2 3 4; 4 5 6]"です。新しい行を意味します。 いくつの行と列があるか知りたい。

答えて

0

ストリーム抽出演算子には、変更可能な既成のオブジェクトが必要であるという問題があります。動的にリサイズできるように、マトリックスクラスを適合させる必要があります。

0

「istream演算子のサイズ」は、ストリームであるため、最初の行列要素を読み取ったときに最後の要素が既に存在することを保証することはできません。最初に文字列全体を読み取って解析し、入力行列のサイズに関する情報を抽出する必要があります。その後、stringstream経由でこの文字列を入力することで、コードを使用することができます。もちろん、行列のサイズを動的に変更できる必要があります。

2

あなたはこのようなすべての行を取得することができます。そして、今、あなたはrowsの各行の文字列を持っている

vector<string> rows; 
string line; 

is.ignore(INT_MAX, '['); // ignores all characters until it passes a [ 

while (std::getline(is, line, ';')) 
    rows.push_back(line); // put each row in rows 

rows.back().erase(rows.back().find(']')); // erase the ending ] 

を、

for (size_t i = 0; i < rows.size(); ++i) { 
    vector<int> items; 
    istringstream strstm(rows[i]); 

    std::copy(istream_iterator<int>(strstm), istream_iterator<int>(), back_inserter(items)); 

    // now items is full of the entries, resize the matrix to hold items.size() 
    // many items and insert each one into it, or whatever 
} 
+0

私はこのエラーを取得:変数を「STD :: istringstream strstm」は初期化が、不完全型 – shizzle

+0

を有します@ shizzle: '#include 'が必要です。 –

1

まず、もちろん、あなたは物事を指定する必要がありますあなたよりも少し厳しいです。 持っています。例えば、"[ 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より大きい任意の長さを有することができ、後行が前の行と同じ長さ を有していなければならない。)

関連する問題