fstream::exception 意外行为

发布于 2024-10-26 13:45:43 字数 1588 浏览 3 评论 0原文

在下面的代码中;知道为什么执行 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

In the code below; any idea why the ifs becomes bad when std::copy is performed?

#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();
}

Here is the output I get.

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

゛时过境迁 2024-11-02 13:45:43

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

您还对事情进行了一些误解:!stream 相当于 stream.fail(),但与 相同流.bad()。 stream.bad() 表示发生了严重故障,例如在您尝试读取数据时硬盘损坏。 stream.fail() 可能意味着更温和(甚至正常)的情况,例如尝试转换失败,可能是因为您读取了一些无法转换为目标类型的数据(例如,流包含“one”并且您正在尝试读取 int)或者因为(如本例所示)您已到达文件末尾。

底线:iostreams 异常很少有多大用处。一些异常被定义为在完全正常、预期的情况下抛出。

The (default constructed) end iterator you've given as the place to stop copying will only compare equal to the other iterator when attempting to read the specified data from the file fails. In this case, it's converted all the data in the file and reached EOF. That means everything has succeeded, but the stream is now in a fail state, so until or unless you reset it, you won't be able to do anything else with that stream.

You've also misinterpreted things a bit: !stream is equivalent to stream.fail(), but that's not the same as stream.bad(). stream.bad() means there's been a serious failure such as a hard drive dying while you were trying to read from it. stream.fail() can mean something much milder (or even normal) such as an attempted conversion failing, possibly because you're read some data that can't be converted to the target type (e.g., the stream contains "one" and you're trying to read an int) or because (as in this case) you've reached the end of the file.

Bottom line: iostreams exceptions are only rarely of much use. Some of the exceptions are defined to be thrown in perfectly normal, expected cases.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文