C++读取超17万行CSV文件失败,仅读取3600行求解决方案
解决CSV读取行数受限的问题
我来帮你排查下代码里的问题——你现在只能读到3600行,甚至想读到1万行都做不到,主要是几个常见的C++文件读取和内存使用的坑导致的,咱们一步步调整:
原代码的核心问题
- 栈内存溢出风险:你用了静态数组
string data[3000][10];,这个数组是在栈上分配的。栈的空间通常只有几MB,虽然3000行看起来不多,但如果每行的字符串内容较长,很容易触发栈溢出,导致程序异常终止。要是想读到1万行,静态数组就更扛不住了。 - 读取逻辑错误:你循环10次用
getline(file, data[i][j], ',')来拆分字段,但每行的最后一个字段后面是换行符,不是逗号!这会导致第10次getline会把下一行的内容读进来,甚至跨越多行,彻底打乱读取节奏,到一定行数后就会读取失败。 - 未检查读取状态:每次
getline之后你都没判断是否成功,当文件读取出现异常(比如字段缺失、文件损坏),程序还会继续循环,导致错误扩散。 - 输出换行逻辑无效:
if (j == 10)永远不会触发,因为j的范围是0到9,应该改成j == 9才会在每行最后一个字段后换行。
修正后的代码
下面是调整后的版本,能稳定读取最多1万行,也适配你的CSV格式:
#include "stdafx.h" #include <iostream> #include <fstream> #include <sstream> #include <vector> #include <string> using namespace std; int main() { ifstream file("Brightest Day.csv"); if (!file.is_open()) { cout << "ERROR: 无法打开文件" << "\n"; return 1; // 打开失败直接退出 } // 用vector动态存储,避免栈溢出,支持扩容到1万行 vector<vector<string>> data; const int MAX_LINES = 10000; // 最多读取1万行 string line; // 逐行读取文件 while (getline(file, line) && data.size() < MAX_LINES) { vector<string> row; stringstream ss(line); string field; // 拆分当前行的字段(按逗号分隔) while (getline(ss, field, ',')) { row.push_back(field); } // 确保每行有10个字段(可选,根据你的CSV情况调整) if (row.size() == 10) { data.push_back(row); } else { cout << "警告:第" << data.size()+1 << "行字段数量不符,跳过\n"; } } // 输出读取到的内容 for (size_t i = 0; i < data.size(); i++) { for (size_t j = 0; j < data[i].size(); j++) { cout << data[i][j] << " | "; if (j == data[i].size() - 1) { // 每行最后一个字段后换行 cout << "\n"; } } } cout << "\n成功读取 " << data.size() << " 行数据\n"; file.close(); return 0; }
关键调整说明
- 改用
vector<vector<string>>:动态分配堆内存,没有栈空间的限制,轻松支持1万甚至更多行的存储。 - 逐行读取拆分:先读整行到
line,再用stringstream拆分字段,完美解决最后一个字段是换行符的问题,读取逻辑更可靠。 - 控制读取行数:通过
data.size() < MAX_LINES限制最多读1万行,避免不必要的内存占用。 - 增加错误检查:文件打开失败直接退出,字段数量不符时给出警告,方便排查CSV格式问题。
- 修复输出换行逻辑:用
j == data[i].size() - 1判断最后一个字段,适配不同字段数的情况(当然你的CSV是10列)。
额外建议
如果CSV里有带逗号的字段(比如用引号包裹的内容,比如"abc,def"),上面的拆分逻辑会出错,这种情况你需要更复杂的CSV解析逻辑,但如果你的CSV没有这种情况,上面的代码完全够用。
内容的提问来源于stack exchange,提问作者rum-and-laughs
相关产品推荐
相关产品推荐

