stoi抛异常而atoi静默返回0:stoi遇非法输入抛invalid_argument或out_of_range,atoi对"abc"或空串均返0;stoi支持进制与解析位置,atoi仅十进制且无位置信息;stoi接受string,atoi需c_str()易致悬空指针。

stoi 会抛异常,atoi 只返回 0
这是最根本的差异:遇到非法输入时,stoi 直接抛 std::invalid_argument 或 std::out_of_range,而 atoi 安静地返回 0——哪怕你传的是 "abc" 或空字符串。这种“静默失败”极易掩盖逻辑错误。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 用
stoi时必须套try/catch,尤其处理用户输入或配置文件解析 - 用
atoi前先用strspn或std::all_of检查字符串是否全为数字(含可选符号),否则"123abc"会被截断成123,而"abc123"得到0 - 如果明确知道输入格式干净(比如自动生成的 JSON 字段),
atoi更轻量,没异常开销
stoi 支持指定进制,atoi 固定十进制
stoi 第二个参数是 size_t* 类型的指针,第三个参数是进制(默认 10);atoi 没有这些能力,且不提供“解析到哪为止”的位置信息。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 解析十六进制字符串如
"0xFF"或"FF",用stoi(s, nullptr, 16);别指望atoi自动识别前缀 - 需要知道解析停在哪(比如字符串后还跟着单位
"123px"),用stoi(s, &idx, 10),idx会存下有效数字结尾索引 -
atoi对"0x123"返回0,不是291——它根本不认前缀
stoi 是 C++11 标准库函数,atoi 来自 C 的 <cstdlib>
stoi 在 <string> 中声明,接受 std::string;atoi 在 <cstdlib> 中,只接受 const char*。这意味着传 std::string 给 atoi 会隐式调用 c_str(),但若该 string 是临时对象,c_str() 返回的指针可能悬空。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 避免
atoi((std::string("123")).c_str())这类写法——临时对象在分号前销毁,c_str()指针失效 - 用
stoi可直接传std::string,无生命周期顾虑 - 跨平台项目若需兼容旧编译器(如 VS2010),
atoi更稳妥,stoi需 C++11 支持
性能差异微乎其微,别为这个选函数
在现代编译器(GCC 9+、Clang 10+、MSVC 2019+)下,两者底层都走类似路径,差异主要在异常处理和类型检查开销。真实场景中,字符串解析本身远比函数调用开销大。
实操建议:
立即学习“C++免费学习笔记(深入)”;
- 不要因为“
atoi快一点”就放弃错误检测——调试时间远大于几纳秒的差异 - 高频循环里解析固定格式整数(如日志行字段),可考虑
std::from_chars(C++17),它不抛异常、不分配内存、支持所有进制,且返回解析状态 - 如果用
atoi,至少加一层封装,比如int safe_atoi(const std::string& s) { return s.empty() ? 0 : atoi(s.c_str()); },避免裸用
真正容易被忽略的是:两种函数都不处理溢出语义的一致性。stoi 遇到超限抛 std::out_of_range,atoi 则依赖 INT_MAX/INT_MIN 截断,结果不可移植。如果你的代码要跑在 16 位嵌入式环境或 Windows 上,务必确认目标平台的 int 大小。










