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

C++调用stol转字符串为整数时抛std::invalid_argument异常崩溃如何解决

问题原因
  1. 源数据文件中存在空行,当getline读取到空行时,后续三次按逗号分隔读取字段后,传入stol的temp变量为空字符串,stol无法转换空串,直接抛出std::invalid_argument异常,这是崩溃的直接原因。
  2. 除此之外,部分行的字段数量不符合预设规则、转换字段存在非数字字符、行尾多余逗号导致最后一次getline拿到空串,都会触发数字转换类异常。
定位方法
  • 在调用stol前添加日志打印,输出当前行内容、temp的取值,可快速定位到异常触发时的非法输入。
  • 对数字转换逻辑添加异常捕获,捕获时打印对应行的原始内容,可快速定位问题行。
解决方案

你可以通过输入合法性校验、异常捕获、非法行过滤三个维度解决问题,修改后的参考代码如下:

string info;
bool flag = false;
int n = 0;
int lineNum = 0; // 增加行号计数方便定位问题
while (getline(fin, info))
{
    lineNum++;
    // 第一步:过滤空行
    if (info.empty()) {
        continue;
    }
    
    stringstream ss(info);
    string temp;

    try {
        getline(ss, totalStudents[n].firstName, ',');
        getline(ss, totalStudents[n].lastName, ',');
        getline(ss, temp, ',');
        // 第二步:转换前先判断字段非空
        if (temp.empty()) {
            cerr << "第" << lineNum << "行学号字段为空,跳过该行" << endl;
            continue;
        }
        totalStudents[n].studentId = stol(temp);

        if(studentID == totalStudents[n].studentId)
        {
            flag = true;
            continue;
        }

        getline(ss, temp, ',');
        if (temp.empty()) {
            cerr << "第" << lineNum << "行考试次数字段为空,跳过该行" << endl;
            continue;
        }
        totalStudents[n].testsTaken = stoi(temp);
        totalStudents[n].testScores = new int [totalStudents[n].testsTaken];

        for(int i = 0; i < totalStudents[n].testsTaken; i++)
        {
            if (!getline(ss, temp, ',')) {
                cerr << "第" << lineNum << "行成绩字段不足,跳过该行" << endl;
                // 注意释放已申请的内存避免泄漏
                delete[] totalStudents[n].testScores;
                goto nextLine; // 直接跳转到下一行处理
            }
            totalStudents[n].testScores[i] = stoi(temp);
        }

        n++;
    } catch (const std::invalid_argument& e) {
        cerr << "第" << lineNum << "行字段转换失败,错误信息:" << e.what() << ",跳过该行" << endl;
    } catch (const std::out_of_range& e) {
        cerr << "第" << lineNum << "行数字超出范围,错误信息:" << e.what() << ",跳过该行" << endl;
    }
nextLine:;
}

fin.close();
额外优化建议
  • 动态申请的testScores数组注意异常场景下的内存释放,避免内存泄漏,更推荐使用std::vector<int>替代原生数组管理成绩,不需要手动管理内存。
  • 可以提前清理行尾多余的逗号,避免最后一个字段读取为空。

内容的提问来源于stack exchange,提问作者William Euan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 23:15:10