开发者

C++ IO file streams: writing from one file to another using operator<< and rdbuf()

I have a question about copying data from one file to another in C++ (fstream) using operator<<. Here is a code snippet that works for me:

    #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
        }
    }

I would like to be certain that after writing, the end of input file in stream in has been reached. However, if I test for in.eof(), it is false, despite the fact that checking the input and output files confirms that the entire contents has been properly copied over. Any ideas on how I would check for in.eof()?


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 check in.eof(). I have tested this fix and it works.


The reason none of the status bits are set in the input file is because you are reading through the streambuf, not the istream; the actual reading takes place in the ostream::operator<<, which doesn't have access to the istream.

I'm not sure it matters, however. The input will be read until streambuf::sgetc returns EOF. Which would cause the eofbit to be set in the istream if you were reading through the istream. The only thing which might prevent this if you were reading through the istream is if streambuf::sgetc threw an exception, which would cause badbit to be set in istream; there is no other mechanism provided for an input streambuf to report a read error. So wrap your out << in.rdbuf() in a try ... catch block, and hope that the implementation actually 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 <<, I don'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).


Try in.rdbuf()->sgetc() == EOF.

Reference: http://www.cplusplus.com/reference/iostream/streambuf/sgetc/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜