fstream :: исключения непредвиденное поведение - PullRequest
1 голос
/ 28 марта 2011

В коде ниже;Любая идея, почему ifs становится плохим при выполнении std :: copy?

#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 Ответ

4 голосов
/ 28 марта 2011

(построенный по умолчанию) итератор end, который вы указали в качестве места остановки копирования, будет сравниваться с другим итератором только в том случае, если попытка чтения указанных данных из файла не удалась.В этом случае он преобразует все данные в файле и достигает EOF.Это означает, что все прошло успешно, , но поток сейчас находится в состоянии сбоя, поэтому до тех пор, пока вы его не сбросите, вы не сможете больше ничего делать с этим потоком.

Вы также немного неверно истолковали вещи: !stream эквивалентно stream.fail(), но это , а не , то же самое, что stream.bad().stream.bad() означает, что произошел серьезный сбой, например, смерть жесткого диска, когда вы пытались прочитать с него.stream.fail() может означать что-то более мягкое (или даже нормальное), такое как неудачная попытка преобразования, возможно, потому что вы читаете некоторые данные, которые не могут быть преобразованы в целевой тип (например, поток содержит «один» и выВы пытаетесь прочитать int) или потому, что (как в этом случае) вы достигли конца файла.

Итог: исключения iostreams редко используются.Некоторые из исключений определены как исключительные в ожидаемых случаях.

...