You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++读取CSV时跳过N/A或空行报错,求解决方案

解决CSV读取时跳过N/A/空值仍触发stof异常的问题

问题根源

你的代码存在三个核心问题导致异常:

  • 空行未提前拦截:遇到空行时,ss >> date >> time会直接执行失败,但你没检查流状态,后续操作依然继续,读取的空内容传给stof就会触发异常。
  • 空值判断错误:temp=="\0"是错误的——getline读取空列时,得到的是空字符串"",而非带单个空字符的"\0"。
  • 仅检查了speed列:solRad和airTemp列如果出现N/A或空值,同样会触发stof的异常,你没处理这些场景。

修复步骤

  1. 提前过滤空行:进入行处理逻辑前,先判断line是否为空,空行直接跳过。
  2. 检查日期时间读取状态:ss >> date >> time执行后,判断流是否处于正常状态,读取失败则跳过该行。
  3. 修正空值判断逻辑:用temp.empty()代替temp=="\0",同时对所有需要转换为数值的列(speed、solRad、airTemp)都做N/A和空值检查。
  4. 可选优化:每次读取列后检查流状态,避免因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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 21:13:19