使用ifstream按分隔符读取文件时后续行数据读取异常求助
解决读取分隔符文本时后续行名称/描述为空的问题
嘿,我一眼就看到你代码里的几个小问题,正是它们导致后续行的名称和描述读不出来:
问题根源拆解
- 循环条件踩坑:
while (File.good())这个判断逻辑有问题——它会在文件读到末尾后,还多跑一次循环。这时候读取的TempString是空的,或者读取不完整,直接导致分割时出错。 substr参数写错了:获取描述的时候,substr的第二个参数是「截取长度」,你写的TempString.length() -1完全不对,应该是从pos2+1到字符串结尾的长度(其实更简单的是只传起始位置,默认就会读到结尾)。- 没处理分隔符的空格:你的文本里
-前后都有空格,直接截取会让名称和描述带前导空格,虽然不是空,但也不符合预期,顺便一起解决了。
修复后的完整代码
#include <string> #include <fstream> #include <vector> #include <algorithm> #include <cctype> // 辅助函数:去掉字符串前后的空格 std::string trim(const std::string& s) { auto start = s.begin(); while (start != s.end() && std::isspace(static_cast<unsigned char>(*start))) { start++; } auto end = s.end(); do { end--; } while (std::distance(start, end) > 0 && std::isspace(static_cast<unsigned char>(*end))); return std::string(start, end + 1); } // 假设你的ItemData结构体是这样的 struct ItemData { int ID; std::string name; std::string description; }; std::vector<ItemData> itemsList; void GetItemData() { std::ifstream File("items.txt"); std::string TempString; // 用getline的返回值做循环条件,确保读到有效行才处理 while (getline(File, TempString)) { // 跳过空行,避免处理无效数据 if (TempString.empty()) continue; ItemData itemData; size_t pos = TempString.find('-'); // 如果找不到第一个分隔符,跳过这行(格式错误) if (pos == std::string::npos) continue; // 读取ID,先trim掉前后可能的空格 itemData.ID = stoi(trim(TempString.substr(0, pos))); size_t pos2 = TempString.find('-', pos + 1); // 找不到第二个分隔符也跳过 if (pos2 == std::string::npos) continue; // 读取名称,trim掉空格 itemData.name = trim(TempString.substr(pos + 1, pos2 - pos - 1)); // 读取描述,只传起始位置就会读到结尾,再trim itemData.description = trim(TempString.substr(pos2 + 1)); itemsList.push_back(itemData); } }
关键修复说明
- 循环条件优化:
while (getline(File, TempString))直接判断是否成功读取一行,从根源上避免了空字符串进入处理逻辑。 - 添加
trim函数:处理分隔符前后的空格,保证数据干净,也避免了因为空格导致的字符串看起来为空的情况。 - 简化描述截取:
substr(pos2 + 1)不需要手动计算长度,C++里只传起始位置的话,默认会截取到字符串结尾,更安全不容易出错。 - 格式检查:增加了对分隔符是否存在的判断,就算文件里有格式错误的行,程序也不会崩溃,只会跳过这些行。
内容的提问来源于stack exchange,提问作者Rodney Muller
相关产品推荐
相关产品推荐

