C++调用stol转字符串为整数时抛std::invalid_argument异常崩溃如何解决
问题原因
- 源数据文件中存在空行,当
getline读取到空行时,后续三次按逗号分隔读取字段后,传入stol的temp变量为空字符串,stol无法转换空串,直接抛出std::invalid_argument异常,这是崩溃的直接原因。 - 除此之外,部分行的字段数量不符合预设规则、转换字段存在非数字字符、行尾多余逗号导致最后一次
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
相关产品推荐
相关产品推荐

