一 问题
使用C++ ifstream来读取文件时,发现在读到文件结尾时会多读一行。测试代码如下,
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{
ifstream inf("data.txt");
if (!inf) {
cerr << "open data.txt fail\n";
return 1;
}
string oneline;
while (inf.eof() == false) { // 问题点
getline(inf, oneline);
cout << oneline << "\n";
}
return 0;
}
data.txt内容如下,
输出如下,
二 解决办法
使用文件流的peek()方法来代替eof()方法,如下,
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main(void)
{
ifstream inf("data.txt");
if (!inf) {
cerr << "open data.txt fail\n";
return 1;
}
string oneline;
while (inf.peek() != EOF) { // 关键行
getline(inf, oneline);
cout << oneline << "\n";
}
return 0;
}
输出如下,
可见最后一行得到了正确的处理。
三 原因探究
《C++ primer 5th》17.5.2节对文件流的peek()方法描述如下,
peek返回输入流中下一个字符的副本,但不会将它从流中删除。peek返回的值仍然留在流中。
所以,通过peek()来提前预判下一个字符是不是文件结束符EOF,就可以让我们提前知道文件流是否已经到了结尾,就可以正确结束输入。
为什么eof()方法不行呢? 以后再探讨…
如果有写的不对的地方,希望能留言指正,谢谢阅读。