fstream ::例外意外行为

时间:2011-03-28 03:03:52

标签: c++ exception fstream

在下面的代码中;知道为什么执行std :: copy时ifs会变坏?

#include <iostream>
#include <fstream>
#include <algorithm>
#include <iterator>

int main(int argc, char* argv[]) {
    std::fstream ifs(argv[1], std::fstream::in | std::fstream::binary);
    std::fstream ofs(argv[2], std::fstream::out | std::fstream::trunc | std::fstream::binary);

    ifs.unsetf(std::ios_base::skipws);

    std::istream_iterator<unsigned char> begin(ifs);
    std::istream_iterator<unsigned char> end;

    std::ostream_iterator<char> begin2(ofs);

    ifs.exceptions(std::fstream::badbit | std::fstream::failbit);
    ofs.exceptions(std::fstream::badbit | std::fstream::failbit);

    if(!ifs)
        std::cerr << "ifs bad" << std::endl;
    if(!ofs)
        std::cerr << "ofs bad" << std::endl;

    try {
        std::copy(begin, end, begin2);
    }
    catch(...) {
        if(ifs.bad())
            std::cerr << "exception: ifs bad" << std::endl;
        if(ifs.fail())
            std::cerr << "exception: ifs fail" << std::endl;
        if(ifs.eof())
            std::cerr << "exception: ifs eof" << std::endl;
    }

    if(!ifs)
        std::cerr << "ifs bad" << std::endl;
    if(!ofs)
        std::cerr << "ofs bad" << std::endl;

    //ofs << ifs.rdbuf();
}

这是我得到的输出。

~$ cp fstream.cpp ~/tmp/fstream/
~$ g++ -ggdb -O0 fstream.cpp

~$ ./a.out a.out xxx.ooo
exception: ifs fail
exception: ifs eof
ifs bad

1 个答案:

答案 0 :(得分:4)

当您尝试从文件读取指定数据失败时,您作为停止复制的位置给出的(默认构造的)end迭代器将仅与其他迭代器进行比较。在这种情况下,它转换了文件中的所有数据并达到了EOF。这意味着一切都已成功,流现在处于失败状态,因此除非您重置它,否则您将无法对该流做任何其他事情。

您还误解了一些事情:!stream相当于stream.fail(),但 stream.bad()相同。 stream.bad()表示当您尝试从中读取硬盘时,会出现严重故障,例如硬盘驱动器死亡。 stream.fail()可能意味着更温和(甚至正常)的事情,例如尝试转换失败,可能是因为您读取了一些无法转换为目标类型的数据(例如,流包含“one”和你正试图阅读int)或因为(在这种情况下)你已经到达了文件的末尾。

底线:iostreams异常很少使用。一些例外被定义为完全正常的预期情况。