C++文件读取末尾空行问题
起因是做gitlet读取文件内容时遇到的内容不匹配错误,后来发现是自己读取文件内容时均使用getline函数,写回时读入的每个字符串都加上换行符,导致文件末尾可能多出换行符。
于是改成了
vector<string> Blob::readContentsForBlob(const string& file){
vector<string> content;
ifstream fin(file);
string line;
// 这样读取可以知道末尾是不是有空行,保证了读取内容一致
while(!fin.eof()){
getline(fin, line);
content.push_back(line);
}
fin.close();
return content;
}
通过返回值最后一项是否为空字符串来判断是否有空行。
平时没有注意过这个问题,于是试着读取其他数据
文件内容
类型一,末尾无空行
1
2
3
类型二,末尾有空行
1
2
3
int读取
以下代码为通常oj题目中读取方式,可以看到类型一和类型二的输出是一样的。
ifstream fin("file.txt");
int n;
while(fin >> n){
cout<<n<<"-";
}
fin.close();
而以下代码则可以区分类型一和类型二
while(!fin.eof()){
fin>>n;
cout<<n<<"-";
}
输出分别为
1-2-3-
1-2-3-3-
对于eof函数,文件实际有效内容读完后,有空行和无空行的结果是不一样的,前者true,会再次进入读取,但是读取失败;后者false,不会再次进入读取。
字符读取
但通过字符输入时,两种代码在末尾无空行时的输出均为
1-2-3-
有空行时输出均为
1-2-3-3-
这是int和char的读取造成的,int要预先看到下一个字符,因此eof函数的判断会提前,而char则不会。
string读取
通过string直接输入时
string s;
while(!fin.eof()){
fin >> s;
cout << s << "-";
}
情况和int一样,也是因为string结束要提前读到下一个字符。
string使用getline输入时
string s;
while(getline(fin, s)){
cout << s << "-";
}
只会读完所有有效行。
综上,只读取所有有效数据时(无论是否有空行),直接使用
while(fin >> n) ...
while(getline(fin, s)) ...
while(fin >> s) ...
while(fin >> ch) ...
如果想判断是否有空行,使用eof函数时即可,这时候一般只在整行读取时使用,方法见文章起始代码。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了