4

2 つのファイルから、そのうちの 1 つの最後に到達するまで読み取りたいと考えています。何か問題が発生した場合、fstream は例外をスローする必要があります。

問題は、eof ビットが設定されているときに不良ビットまたは失敗ビットも設定されることです。

ifstream input1;
input1.exceptions(ios_base::failbit | ios_base::badbit);
input1.open("input1", ios_base::binary | ios_base::in);

ifstream input2;
input2.exceptions(ios_base::failbit | ios_base::badbit);
input2.open("input2", ios_base::binary | ios_base::in);

ofstream output;
output.exceptions(ios_base::failbit | ios_base:: badbit);
output.open("output", ios_base::binary | ios_base::out | ios_base::trunc);

char in1, in2, out;

while(!input1.eof() && !input2.eof()) {
    input1.read((char*) &in1, 1);
    input2.read((char*) &in2, 1);
    out = in1^in2;
    output.write((const char*) &out, 1);
}

input1.close();
input2.close();
output.close();

これはにつながります

$ ./test
terminate called after throwing an instance of 'std::ios_base::failure'
  what():  basic_ios::clear

それを正しく行う方法は?

4

3 に答える 3

6

コードの基本的な問題はFAQです。eof()C/C++ では (他のいくつかの言語とは異なり)ファイルの終わりを超えて読み取るまで true に設定されないため、読み取りループのテスト条件として使用しないでください。したがって、ループの本体も 1 回入力eof()れます。何度も。

慣用的に正しい手順は、正しいポイントで終了が発生するように、読み取り操作自体をループ状態にすることです。

  while ( input1.get(in1) && input2.get(in2) ) { /* etc */ }
  // here, after the loop, you can test eof(), fail(), etc 
  // if you're really interested in why the loop ended.

このループは、より小さな入力ファイルを使い果たすことで自然に終了します。これはまさにあなたが望むものです。

于 2013-01-13T20:07:19.073 に答える
0

例外をまったくスローせずに、input1.readまたはistream::getwhile条件で使用してください

while (input1.get(in1) && input2.get(in2)) {
...
}

ループ本体の文字を読み取ると、出力に追加の文字が含まれ、対応する入力文字はありません。たぶんこれが理由で、std::ios::exeptionsそもそも使用した理由です。

于 2013-01-13T17:07:59.477 に答える
0

チェックをすべて削除するだけ.eof() if(fstream)です (eof bad と fail)。

そのため、while を次のように書き直します。

 while(input1 && input2)

そして、ストリームの最後の 1 つに対して eof() が true を返すことを確認します。

お役に立てれば。

于 2013-01-13T16:54:58.500 に答える