C++使用std::stoi转字符串求和时触发std::invalid_argument异常问题
问题分析与解决方案
为什么会抛出std::invalid_argument异常?
这个异常是std::stoi抛出的,核心原因是你在调用它的时候传入了空字符串。比如当输入字符串以字母开头(比如"a123"),第一次循环遇到字母'a'时,x还没收集到任何数字,此时执行std::stoi(x)就会触发异常——空字符串无法被解析为整数。
除此之外,你的代码还有两个逻辑漏洞:
- 判断数字的条件不够严谨:
s[i] < 'A'虽然能覆盖数字(数字ASCII码是48-57,'A'是65),但会误判其他ASCII码小于'A'的非数字字符(比如'!'、'@'等)。 - 循环结束后未处理剩余数字:如果输入字符串以数字结尾(比如
"abc123"),循环结束后x中还有未处理的数字,会导致这部分数值被遗漏。
修复后的代码
#include <iostream> #include <string> #include <cctype> // 用于isdigit函数,准确判断数字字符 using namespace std; int main() { int t; cin >> t; while (t--) { string s; cin >> s; string x = ""; int y = 0; for (int i = 0; i < s.length(); i++) { // 准确判断当前字符是否为数字 if (isdigit(s[i])) { x += s[i]; } else { // 只有当x不为空时,才执行转换和累加操作 if (!x.empty()) { y += stoi(x); x.clear(); // 清空x,准备收集下一组数字 } } } // 处理循环结束后剩余的数字(比如字符串结尾是数字的情况) if (!x.empty()) { y += stoi(x); } cout << y << endl; } return 0; }
关键修改点说明
- 用
std::isdigit(s[i])替代s[i] < 'A',精准判断数字字符,避免误判非数字字符。 - 在调用
stoi之前,先检查x是否为空(!x.empty()),确保只有有效的数字字符串才会被转换,从根源避免异常。 - 循环结束后新增检查逻辑,处理字符串末尾的数字,避免结果遗漏。
测试案例验证
比如输入:
2 abc123def45 xyz789
输出会是:
168 789
完全符合预期,且不会再抛出异常。
内容的提问来源于stack exchange,提问作者Heet Mehta
相关产品推荐
相关产品推荐

