Harry Asked:2020-05-27 12:12:03 +0000 UTC2020-05-27 12:12:03 +0000 UTC 2020-05-27 12:12:03 +0000 UTC 正确使用文件结束检查 772 使用代码时 while(!feof(file)) { // Чтение из файла } 在 C 或 while(!file.eof()) { // Чтение из файла } 在 C++ 中你会遇到麻烦——例如,一个额外的读取行。为什么?如何正确检查是否已到达文件末尾? c++ 2 个回答 Voted Best Answer Harry 2020-05-27T12:12:03Z2020-05-27T12:12:03Z 到达文件末尾的标志仅在尝试读取超出文件末尾时设置。因此,如果循环体不检查从文件中读取是否成功,最后一次读取将完全是不成功的读取,它将设置到达文件末尾的标志(对你来说它会看起来像,例如,最后一行再次读取,如果它在读取缓冲区中)。 最好while通过检查循环头来执行读取本身 - 例如,在 C 程序中它可能看起来像这样 while(fread(&data,sizeof(data),1,file)==1) { // Обработка считанных данных } /* Или, скажем, while(fgets(buf, bufsize, file)) { .... } */ if (feof(file)) // Достигнут конец файла puts("Ошибка чтения: достигнут конец файла"); else if (ferror(file)) { puts("Ошибка чтения файла"); 或在 C++ 中 - 像 for(int n; file >> n; ) { // Обработка считанного значения n } if (file.bad()) std::cout << "Ошибка ввода-вывода при чтении\n"; else if (file.eof()) std::cout << "Достигнут конец файла\n"; else if (file.fail()) std::cout << "Неверный формат данных\n"; magrif 2020-08-12T07:31:05Z2020-08-12T07:31:05Z 另外,除了eof标志外,读取整个文件后,还可以设置fail标志,如果我们想将光标设置到fin.seekg(0, fin.beg)的开头,我们就不会读取任何事情,因为 未清除失败标志。您可以使用fin.clear()重置它。当前状态可以通过 fin.rdstate()推断: ifstream fin; fin.open("E://1.txt", ios_base::in); string str; while(getline(fin, str)) { cout<< str<< " " << fin.rdstate() << endl ; } if (fin.bad()) std::cout << "bad" << endl; if (fin.eof()) std::cout << "eof" << endl; if (fin.fail()) std::cout << "bad | fail" << endl; fin.clear(); fin.seekg(0, fin.beg); if (fin.bad()) std::cout << "bad" << endl; if (fin.eof()) std::cout << "eof" << endl; if (fin.fail()) std::cout << "bad | fail" << endl; while(getline(fin, str)) { cout<<str<< " " << fin.rdstate() << endl ; }
到达文件末尾的标志仅在尝试读取超出文件末尾时设置。因此,如果循环体不检查从文件中读取是否成功,最后一次读取将完全是不成功的读取,它将设置到达文件末尾的标志(对你来说它会看起来像,例如,最后一行再次读取,如果它在读取缓冲区中)。
最好
while
通过检查循环头来执行读取本身 - 例如,在 C 程序中它可能看起来像这样或在 C++ 中 - 像
另外,除了eof标志外,读取整个文件后,还可以设置fail标志,如果我们想将光标设置到fin.seekg(0, fin.beg)的开头,我们就不会读取任何事情,因为 未清除失败标志。您可以使用fin.clear()重置它。当前状态可以通过 fin.rdstate()推断: