C++ std::fstream getline遇长行停止读取的解决方法问询
处理std::fstream getline长行的规范方法
当使用固定大小缓冲区的std::fstream::getline()读取长行时,若缓冲区填满仍未遇到换行符,流会设置failbit,此时后续读取操作会被阻塞。要实现类似fgets()的逐段读取长行效果,需按以下规范步骤处理:
核心逻辑
- 每次调用
getline()后,检查流状态:若failbit被设置且未到eof(),说明是缓冲区不足导致的"假失败" - 通过
gcount()确认读取的字节数等于缓冲区大小减一(getline()会预留一个字节存储终止符),验证是长行截断的情况 - 清除
failbit,继续读取当前行的剩余部分 - 当读取到换行符时,确保该字符被流消费,避免影响下一行读取
修改后的示例代码
#include <fstream> #include <iostream> #include <cstring> #include <ios> int main(){ char buffer[10]; const size_t buffer_size = sizeof(buffer); std::string filename{"test.txt"}; std::fstream file(filename, std::ios_base::in | std::ios_base::binary); if(file.is_open()){ while(true){ file.getline(buffer, buffer_size); std::streamsize bytes_read = file.gcount(); // 输出读取到的内容 if(bytes_read > 0){ std::cout << "Read " << std::strlen(buffer) << "/" << bytes_read << ":" << buffer << std::endl; } // 处理长行截断的情况 if(file.fail() && !file.eof()){ // 清除failbit,继续读取当前行剩余部分 file.clear(file.rdstate() & ~std::ios::failbit); } else { // 到达文件末尾或读取到换行符,结束当前行处理 if(file.eof()) break; } } } return 0; }
代码说明
- 用
buffer_size固定缓冲区大小,避免硬编码 - 每次读取后通过
gcount()获取实际读取的字节数(包含截断部分) - 当
failbit触发但未到文件末尾时,清除错误标志继续读取,直到遇到换行符或文件结束
若将缓冲区大小改为4(对应原示例的readBites=4),测试长行1234567890时,输出会符合期望:
Read 3/3:123 Read 3/3:456 Read 3/3:789 Read 1/1:0
内容的提问来源于stack exchange,提问作者Vladlen
相关产品推荐
相关产品推荐

