将CSV文件加载到std::vector<struct>时遇执行跳转与循环异常
CSV加载到std::vector- 的问题解决
问题根源分析
你的代码有两个核心问题,和使用结构体vector无关——这个选择反而比嵌套string vector更合理,问题出在文件操作和循环逻辑上:
- 未检查文件是否成功打开:第一个函数里没有判断
fileCon.open(filePath)是否成功,如果文件路径错误、文件不存在或无权限,fileCon会处于无效状态,peek()直接返回EOF,外层循环不执行,直接跳转到return items;,这就是调试时的跳转现象。 - 内层while循环逻辑完全错误:内层循环判断
fileCon.peek() != '\n',但循环体里一次就读取了整行的所有字段(最后一个getline以'\n'为分隔符),执行完后文件指针已经移动到下一行开头,此时peek()的结果肯定不是'\n',导致内层循环反复执行,陷入死循环;同时重复读取会导致数据错乱、文件状态异常。
修正后的代码
以下是修复后的版本,同时优化了读取逻辑,更鲁棒:
#include <fstream> #include <vector> #include <sstream> #include <string> #include <iostream> // 假设你的Item结构体定义如下(根据字段推断) struct Item { std::string marca; std::string modelo; std::string cv; std::string m2h; std::string preço; }; std::vector<Item> LoadDataFromFileStruct(std::string filePath) { std::ifstream fileCon(filePath); // 直接用ifstream,只读模式更合适 std::vector<Item> items{}; // 检查文件是否成功打开 if (!fileCon.is_open()) { std::cout << "无法打开文件" << std::endl; return items; } std::string line; // 逐行读取文件,直到文件结束 while (std::getline(fileCon, line)) { Item item{}; std::stringstream ss(line); // 将整行内容放入stringstream,方便拆分 // 按逗号拆分字段,赋值给Item的成员 std::getline(ss, item.marca, ','); std::getline(ss, item.modelo, ','); std::getline(ss, item.cv, ','); std::getline(ss, item.m2h, ','); std::getline(ss, item.preço); // 最后一个字段读取到行尾(不需要逗号分隔符) items.push_back(item); } fileCon.close(); return items; }
关键修改说明
- 改用std::ifstream:只读模式更符合读取CSV的场景,避免意外修改文件。
- 增加文件打开检查:及时发现文件无法打开的情况,避免后续无效操作。
- 逐行读取+stringstream拆分:先读取整行到string,再用stringstream拆分字段,比直接操作文件流更可靠,能避免因字段内容包含特殊字符(比如逗号)导致的读取错误(如果你的CSV有引号包裹字段的场景,还需要进一步处理,但基础场景下这个逻辑足够)。
- 移除多余的内层循环:每一行对应一个Item,一次拆分完成即可,不需要内层循环重复读取。
补充说明
你之前的LoadDataFromFile函数能运行,但也存在逻辑瑕疵:比如celStr.back() == '\n'的判断几乎不会触发,因为getline(fileCon, celStr, ',')会把逗号作为分隔符,celStr里不会包含换行符。如果要优化那个函数,同样可以用getline读整行+stringstream拆分的方式,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Pedro Rocha
相关产品推荐
相关产品推荐

