C++读取TXT文件存入map<int,string>后输出空行问题求助
解决C++读取文件到map后输出空行的问题
问题场景
尝试用C++读取PUBLISHERS.txt文件内容,将其存入map<int, string>类型变量,但打印map时得到8个空行。相关文件内容和代码如下:
PUBLISHERS.txt内容
1 Apress Media 2 John-Wiley 3 McGraw-Hill 4 Microsoft Press 5 Packt Publishing 6 Pearson Education 7 Prentice-Hall
原代码(main.cpp)
#include <iostream> #include <fstream> #include <string> #include <map> #include <iomanip> using namespace std; int main() { // Open Files ifstream publishers_file("../Publishers.txt"); // Error Log if failed if (!publishers_file.is_open()) { cout << "Error opening input file." << endl; return 1; } // create vector map map<int, string> publishers; // Read publishers data int publisherid; string publishername; while (publishers_file >> publisherid) { getline(publishers_file, publishername); //below this line is generated by gpt size_t startpos = publishername.find_first_not_of(" \t"); if (startpos != string::npos) { publishername = publishername.substr(startpos); } else { publishername.clear(); } if (!publishername.empty()) { publishers[publisherid] = publishername; } } publishers_file.close(); // Test int i = 0; for (const auto& pair : publishers) { cout << ++i << ": " << pair.first << " " << pair.second << endl; } return 0; }
问题原因
原代码混合使用>>运算符和getline()读取内容,存在以下核心问题:
>>读取整数后,输入流指针停在整数后的空白字符(空格、换行等)处,若文件存在空白行或读取到末尾时,getline()会读取空字符串,导致出版社名称被清空,无法存入map。- 文件名大小写不匹配(代码中为
Publishers.txt,实际文件是PUBLISHERS.txt),在区分大小写的系统中会导致文件打开失败,后续逻辑产生异常输出。 - 未处理文件中的空行,若文件末尾存在空行,会触发无效的读取循环。
解决方案
改用先读取整行,再解析每行内容的方式,规避混合读取的流指针问题,同时增加空行处理和文件名匹配修正:
修改后的代码如下:
#include <iostream> #include <fstream> #include <string> #include <map> #include <sstream> using namespace std; int main() { ifstream publishers_file("../PUBLISHERS.txt"); // 修正文件名大小写 if (!publishers_file.is_open()) { cout << "Error opening input file." << endl; return 1; } map<int, string> publishers; string line; while (getline(publishers_file, line)) { if (line.empty()) { continue; // 跳过空行 } istringstream line_stream(line); int publisherid; string publishername; // 读取id后跳过空白,再读取剩余内容作为名称 if (line_stream >> publisherid && getline(line_stream >> ws, publishername)) { publishers[publisherid] = publishername; } } publishers_file.close(); // 打印测试 int i = 0; for (const auto& pair : publishers) { cout << ++i << ": " << pair.first << " " << pair.second << endl; } return 0; }
关键改进点
- 先读取整行再解析:用
getline()读取每行内容,通过istringstream拆分id和名称,避免流指针错位问题。 - 空行过滤:跳过文件中的空白行,避免无效解析。
- 空白字符处理:用
line_stream >> ws自动跳过id后的所有空白,确保正确读取完整的出版社名称。 - 文件名修正:匹配实际文件名的大小写,避免文件打开失败。
验证结果
修改后运行代码,会正确读取7条出版社数据,输出如下:
1: 1 Apress Media 2: 2 John-Wiley 3: 3 McGraw-Hill 4: 4 Microsoft Press 5: 5 Packt Publishing 6: 6 Pearson Education 7: 7 Prentice-Hall
内容的提问来源于stack exchange,提问作者Tenardie
相关产品推荐
相关产品推荐

