【问题标题】:C++ fstream: throwing exception when reaching eofC ++ fstream:到达eof时抛出异常
【发布时间】:2012-12-27 15:53:10
【问题描述】:

我想从两个文件中读取,直到到达其中一个文件的末尾。 如果出现问题,fstream 应该抛出异常。

问题是,在设置 eof 位时,也会设置 bad 或 fail 位。

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

怎么做才对?

【问题讨论】:

标签: c++


【解决方案1】:

代码中的基本问题是FAQ。你永远不应该使用 eof() 作为读取循环的测试条件,因为在 C/C++ 中(不同于 一些其他语言)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.

这个循环会随着较小的输入文件的耗尽而自然结束,这正是你想要的。

【讨论】:

  • 谢谢,但是当到达文件末尾时,这段代码仍然会抛出异常。
  • 那是因为您要求例外。关键是您根本不需要任何异常来检测输入的结束。
  • 此外,您真的不想在此 API 中使用异常。见,例如this 和上面对代码片段的更新
【解决方案2】:

不要抛出异常,在你的 while 条件中使用 input1.readistream::get

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

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

【讨论】:

    【解决方案3】:

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

    所以将while改写为:

     while(input1 && input2)
    

    然后可能验证 eof() 对最后一个流返回 true。

    希望这会有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多