C ++ fstream:到达eof时抛出异常

时间:2013-01-13 16:49:40

标签: c++

我想从两个文件中读取,直到我到达其中一个文件的末尾。 如果出现问题,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

如何正确做到?

3 个答案:

答案 0 :(得分:5)

代码中的基本问题是FAQ。您永远不应该使用eof()作为读取循环的测试条件,因为在C / C ++中(其他一些语言不同)eof()在读取之前不会设置为true em>过去文件的结尾,因此循环的主体将在中输入太多次。

惯用正确的过程是将读取操作本身置于循环条件中,以便退出发生在正确的位置:

  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.

这个循环会自动结束较小的输入文件,这正是你想要的。

答案 1 :(得分:0)

只需删除.eof() if(fstream)检查所有位(eof bad and fail)。

所以重新写下来:

 while(input1 && input2)

然后可以验证eof()在最后一个流中返回true。

希望这有帮助。

答案 2 :(得分:0)

根本不要抛出异常并在你的条件中使用input1.readistream::get

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

如果读取循环体中的字符,输出中将有一个附加字符,没有相应的输入字符。也许这就是为什么你首先使用std::ios::exeptions的原因。