C++ IO 文件流:使用运算符<<从一个文件写入另一个文件和 rdbuf()
我有一个关于使用运算符<< 在 C++ (fstream) 中将数据从一个文件复制到另一个文件的问题。这是一个适合我的代码片段:
#include <fstream>
#include <string>
void writeTo(string &fname, ofstream &out){
ifstream in;
in.open(fname.c_str(),fstream::binary);
if(in.good()){
out<<in.rdbuf();
in.close();
}else{
//error
}
}
我想确定写入后,已到达流 in
中输入文件的末尾。但是,如果我测试 in.eof()
,它是 false
,尽管检查输入和输出文件确认整个内容已被正确复制。关于如何检查 in.eof()
有什么想法吗?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当试图读取一个字符时,EOF 位被设置,但没有一个可用(即您已经消耗了字符串中的所有内容)。显然
std::ostream::operator<<()
不会尝试读取字符串末尾,因此该位永远不会被设置。您应该能够通过尝试访问下一个字符来解决此问题:在检查
in.eof()
之前添加in.peek()
。我已经测试了这个修复并且它有效。EOF-bit is set when trying to read a character, but none is available (i.e. you have already consumed everything in the string). Apparently
std::ostream::operator<<()
does not attempt to read past the end of the string, so the bit is never set.You should be able to get around this by attempting to access the next character: add
in.peek()
before you checkin.eof()
. I have tested this fix and it works.尝试
in.rdbuf()->sgetc() == EOF
。参考:http://www.cplusplus.com/reference/iostream/streambuf/sgetc/
Try
in.rdbuf()->sgetc() == EOF
.Reference: http://www.cplusplus.com/reference/iostream/streambuf/sgetc/
输入文件中没有设置任何状态位的原因是
您正在阅读
streambuf
,而不是istream
;实际的读取发生在
ostream::operator<<
中,它没有访问
istream
。不过,我不确定这是否重要。输入将被读取,直到
streambuf::sgetc
返回EOF
。这会导致eofbit
如果您正在阅读
istream
,请在istream
中设置。这如果您正在阅读,唯一可能阻止这种情况发生的事情
istream
是如果streambuf::sgetc
抛出异常,这会导致badbit
在istream
中设置;没有提供其他机制输入
streambuf
报告读取错误。因此,将您的包裹起来 <<
在in.rdbuf()
try ... catch
块中,并希望执行实际上确实检查硬件错误。 (我最近没查过,
但许多早期的实现完全忽略了读取错误,处理
它们作为正常的文件结尾。)
当然,因为您实际上是在读取字节(尽管有
<<
,我不明白如何调用此格式化输入),您不必
考虑第三种可能的错误来源,即格式错误(例如
输入 int 时为“abc”)。
The reason none of the status bits are set in the input file is because
you are reading through the
streambuf
, not theistream
; the actualreading takes place in the
ostream::operator<<
, which doesn't haveaccess to the
istream
.I'm not sure it matters, however. The input will be read until
streambuf::sgetc
returnsEOF
. Which would cause theeofbit
to beset in the
istream
if you were reading through theistream
. Theonly thing which might prevent this if you were reading through the
istream
is ifstreambuf::sgetc
threw an exception, which would causebadbit
to be set inistream
; there is no other mechanism providedfor an input
streambuf
to report a read error. So wrap yourout <<
in ain.rdbuf()
try ... catch
block, and hope that the implementationactually does check for hardware errors. (I haven't checked recently,
but a lot of early implementations totally ignored read errors, treating
them as a normal end of file.)
And of course, since you're literally reading bytes (despite the
<<
, Idon't see how one could call this formatted input), you don't have to
consider the third possible source of errors, a format error (such as
"abc" when inputing an int).