C++读取CSV时跳过N/A或空行报错,求解决方案
解决CSV读取时跳过N/A/空值仍触发stof异常的问题
问题根源
你的代码存在三个核心问题导致异常:
- 空行未提前拦截:遇到空行时,
ss >> date >> time会直接执行失败,但你没检查流状态,后续操作依然继续,读取的空内容传给stof就会触发异常。 - 空值判断错误:
temp=="\0"是错误的——getline读取空列时,得到的是空字符串"",而非带单个空字符的"\0"。 - 仅检查了speed列:solRad和airTemp列如果出现N/A或空值,同样会触发
stof的异常,你没处理这些场景。
修复步骤
- 提前过滤空行:进入行处理逻辑前,先判断
line是否为空,空行直接跳过。 - 检查日期时间读取状态:
ss >> date >> time执行后,判断流是否处于正常状态,读取失败则跳过该行。 - 修正空值判断逻辑:用
temp.empty()代替temp=="\0",同时对所有需要转换为数值的列(speed、solRad、airTemp)都做N/A和空值检查。 - 可选优化:每次读取列后检查流状态,避免因CSV格式错位导致后续读取混乱。
修改后的代码示例
istream & operator >>(istream & input, wLogVec & data) { string line; int count = 0; while(getline(input, line)) { // 直接跳过空行 if(line.empty()) continue; if(count!=0) { stringstream ss(line); string temp; Date date; Time time; // 检查日期时间读取是否成功,失败直接跳过 if(!(ss >> date >> time)) continue; // 跳过不需要的列 for(int i=0; i<9; i++) { getline(ss, temp, ','); } // 处理speed列,做空值和N/A检查 getline(ss, temp, ','); if(temp =="N/A" || temp.empty()) continue; float speed = stof(temp); // 处理solRad列,同样做检查 getline(ss, temp, ','); if(temp =="N/A" || temp.empty()) continue; float solRad = stof(temp); // 跳过不需要的列 for(int i=0; i<5; i++) { getline(ss, temp, ','); } // 处理airTemp列,做检查 getline(ss, temp); if(temp =="N/A" || temp.empty()) continue; float airTemp = stof(temp); data.Add(new WindLog(date, time, speed, solRad, airTemp)); } count++; } return input; }
额外建议
如果CSV里的空列可能包含空格(比如 , ,这种格式),可以写个简单的字符串清理函数,避免空格导致判断失效:
string trim(const string &s) { auto start = s.begin(); while(start != s.end() && isspace(*start)) start++; auto end = s.end(); do { end--; } while(distance(start, end) > 0 && isspace(*end)); return string(start, end + 1); }
在判断前先执行temp = trim(temp);,能让代码更鲁棒。
内容的提问来源于stack exchange,提问作者T4ctician
相关产品推荐
相关产品推荐

