Файловые потоки C ++ IO: запись из одного файла в другой с использованием операторов << и rdbuf () - PullRequest
2 голосов
/ 24 мая 2011

У меня есть вопрос о копировании данных из одного файла в другой в C ++ (fstream) с помощью оператора <<. Вот фрагмент кода, который работает для меня: </p>

    #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()?

Ответы [ 3 ]

1 голос
/ 24 мая 2011

EOF-бит устанавливается при попытке прочитать символ, но ни один не доступен (т.е. вы уже израсходовали все в строке). Очевидно, std::ostream::operator<<() не пытается прочитать после конца строки, поэтому бит никогда не устанавливается.

Вы сможете обойти это, пытаясь получить доступ к следующему символу: добавьте in.peek() перед проверкой in.eof(). Я проверил это исправление, и оно работает.

1 голос
/ 24 мая 2011

Причина, по которой ни один из битов состояния не установлен во входном файле, заключается в том, что вы читаете через streambuf, а не istream; Настоящий чтение происходит в ostream::operator<<, который не имеет доступ к istream.

Однако я не уверен, что это имеет значение. Ввод будет читаться до streambuf::sgetc возвращает EOF. Что заставит eofbit быть установите в istream, если вы читали через istream. Единственное, что могло бы предотвратить это, если бы вы читали через istream - если streambuf::sgetc сгенерировал исключение, которое вызвало бы badbit устанавливается в istream; другого механизма не предусмотрено для ввода streambuf сообщить об ошибке чтения. Так что заверните ваш out << in.rdbuf() в try ... catch блок и надейтесь, что реализация на самом деле проверяет наличие аппаратных ошибок. (Я не проверял недавно, но многие ранние реализации полностью игнорировали ошибки чтения, рассматривая их как обычный конец файла.)

И, конечно, поскольку вы буквально читаете байты (несмотря на <<, я не вижу, как можно назвать этот форматированный ввод), вам не нужно рассмотрим третий возможный источник ошибок, ошибку формата (например, «abc» при вводе целого).

0 голосов
/ 24 мая 2011

Попробуйте in.rdbuf()->sgetc() == EOF.

Ссылка: http://www.cplusplus.com/reference/iostream/streambuf/sgetc/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...