#c #stl #fstream #ifstream
#c #stl #fstream #ifstream
Вопрос:
У меня вопрос о копировании данных из одного файла в другой в C (fstream) с использованием operator<< . Вот фрагмент кода, который работает для меня:
#include <fstream>
#include <string>
void writeTo(string amp;fname, ofstream amp;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()
?
Комментарии:
1.
eof
устанавливается при попытке чтения после конца ввода, а не при достижении его.2. Попробуйте, возможно, только «out << in;». Возможно, работа напрямую с rdbuf() не влияет на флаги in .
Ответ №1:
Бит EOF устанавливается при попытке прочитать символ, но ни один из них не доступен (т. Е. вы уже использовали все, что есть в строке). По-видимому, std::ostream::operator<<()
не пытается прочитать дальше конца строки, поэтому бит никогда не устанавливается.
Вы должны быть в состоянии обойти это, попытавшись получить доступ к следующему символу: добавьте in.peek()
перед проверкой in.eof()
. Я протестировал это исправление, и оно работает.
Комментарии:
1. Я хотел бы знать, почему это неправильно, тем более, что предложенное мной исправление работает. Широко документировано, что бит EOF не устанавливается при чтении последнего символа в файле: только при попытке чтения после конца файла.
2. Я имел в виду
operator<<
, поскольку он используется для чтения изin
:out << in.rdbuf()
. Поскольку чтение изin.rdbuf()
оставляетin
пустым и не устанавливает бит EOF, попытка прочитать один символ (например, сin.peek()
) установит бит EOF [при попытке чтения после конца потока].3. Хорошо, я удалил все свои комментарии, поскольку я совершенно неправильно понял, что вы говорили. Прошу прощения.
4. Не беспокойтесь. Спасибо за обсуждение.
Ответ №2:
Причина, по которой во входном файле не задан ни один из битов состояния, заключается в том, что вы читаете через streambuf
, а не istream
ostream::operator<<
; фактическое чтение происходит в istream
, у которого нет доступа к , ,.
Однако я не уверен, что это имеет значение. Входные данные будут считываться до streambuf::sgetc
возврата EOF
. Что привело бы к тому, что eofbit
было бы установлено в istream
, если бы вы читали через istream
. Единственное, что могло бы предотвратить это, если бы вы читали через istream
, это если streambuf::sgetc
возникло исключение, которое заставило бы badbit
быть установленным в istream
; другого механизма, предоставляемого для ввода streambuf
сообщения об ошибке чтения, не предусмотрено. Итак, оберните свой out <<
в
in.rdbuf() try ... catch
блок и надейтесь, что реализация действительно проверяет наличие аппаратных ошибок. (Я недавно не проверял, но многие ранние реализации полностью игнорировали ошибки чтения, рассматривая их как обычный конец файла.)
И, конечно, поскольку вы буквально считываете байты (несмотря на <<
, я не понимаю, как можно было бы вызвать этот форматированный ввод), вам не нужно учитывать третий возможный источник ошибок, ошибку формата (такую как «abc» при вводе int).
Ответ №3:
Попробуйте in.rdbuf()->sgetc() == EOF
.
Ссылка: http://www.cplusplus.com/reference/iostream/streambuf/sgetc /