我想从两个文件中读取,直到我到达其中一个文件的末尾.如果出现问题,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();
Run Code Online (Sandbox Code Playgroud)
这导致
$ ./test
terminate called after throwing an instance of 'std::ios_base::failure'
what(): basic_ios::clear
Run Code Online (Sandbox Code Playgroud)
怎么做对了?
您的代码中的基本问题是常见问题解答.你永远不应该使用eof()作为读取环路的测试条件,因为在C/C++(不像一些其他语言)eof()没有被设置为true,直到您已经阅读过去的文件的末尾,因此循环体将进入过一次很多次
惯用的正确过程是将读取操作本身置于循环条件中,以便退出发生在正确的点:
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.
Run Code Online (Sandbox Code Playgroud)
这个循环将自然地结束较小的输入文件,这正是你想要的.