std::stoi 会抛 invalid_argument 或 out_of_range 异常,无法处理空字符串、非法字符、超范围数等;strtol 更可控,可获解析位置和溢出信息;atoi 无错误反馈,仅适用于可信场景。

stoi 会抛异常,不是所有字符串都能直接转
用 std::stoi 转字符串前得先确认它真能转——空字符串、纯空格、超范围数字、带非法字符(比如 "123abc")都会触发 std::invalid_argument 或 std::out_of_range 异常。
- 默认只读开头连续数字部分,
" -42xyz"能转出-42;但"abc123"直接报invalid_argument - 超出
int范围(如"2147483648")会抛out_of_range,不是截断也不是静默返回 0 - 想跳过前导空格?可以,
stoi本来就会自动跳;但不会跳注释符、制表符以外的 Unicode 空白(比如 )
需要容错时别硬套 stoi,改用 strtol 更可控
std::stoi 是 strtol 的封装,但扔掉了关键控制权:无法知道实际解析到哪、有没有剩余字符、是否溢出但还没超 long 范围。
- 用
strtol可以拿到结束指针:char* end; long v = strtol(s.c_str(), &end, 10);,然后检查*end == '\0'判断是否全串有效 -
strtol遇到无效字符返回 0,但会把end指向第一个非法位置,比stoi的异常机制更适合做校验型解析 - 注意
strtol返回long,转int前要手动检查是否在INT_MIN~INT_MAX内,否则有未定义行为
stoi 的 base 参数容易被忽略,默认是 10 不是自动推断
写 stoi("0xFF") 不会得到 255,它按十进制解析,结果是 0;十六进制必须显式传 16,八进制传 8,二进制传 2。
-
stoi("010", nullptr, 0)中的0表示“自动识别前缀”,这时"010"→ 8(八进制),"0x10"→ 16(十六进制) - 但
stoi("10", nullptr, 0)还是按 10 解析,因为没前缀;0并不等于“智能猜”,只是支持前缀识别 - 如果字符串含前导
0b(C++14 二进制字面量风格),stoi不识别,得自己截掉或换正则预处理
性能敏感场景下,atoi 比 stoi 快但完全没错误反馈
atoi 是 C 函数,不抛异常、不检查溢出、不报告解析位置,失败一律返回 0——而 0 本身可能是合法输入,根本分不清成功失败。
立即学习“C++免费学习笔记(深入)”;
- 仅适用于“我 100% 确信这字符串是干净整数”的内部计算场景,比如配置文件里写死的
timeout=30 - 和
stoi相比,省去了异常栈展开开销,实测快 2–3 倍,但代价是把错误检测责任全推给调用方 - 不要用
atoi处理用户输入、网络数据、日志行等不可信来源;宁可多写两行try/catch也别埋隐患
真正麻烦的从来不是选哪个函数,而是怎么界定“这个字符串到底算不算一个合法整数”——空格算不算?小数点后面要不要截?科学计数法认不认?这些边界一旦没对齐,stoi 抛的异常和 strtol 返回的 end 指针,都只是帮你定位问题的工具,不是替你做决定的裁判。










