C++ string怎么转整数 C++ stoi函数与异常捕获处理【转换】

8次阅读

std::stoi 转换失败时抛 std::invalid_argument 或 std::out_of_range 异常;前者对应格式错误(如空字符串、纯字母),后者对应数值溢出(如超出 int 范围)。

C++ string怎么转整数 C++ stoi函数与异常捕获处理【转换】

stoi 转换失败时抛什么异常

std::stoi 在无法解析为有效整数时(比如空字符串、纯字母、超出 int 范围),会抛出 std::invalid_argumentstd::out_of_range。前者对应格式错误,后者对应数值溢出——不是返回 0 或 -1,而是直接崩溃,除非你捕获。

必须用 try-catch 包裹 stoi 吗

是的,只要输入来源不可控(如用户输入、文件读取、网络响应),就必须用 try/catch。不加捕获的 stoi 在异常时会调用 std::terminate,程序直接退出。

  • 安全写法:
    try {     int x = std::stoi(s); } catch (const std::invalid_argument&) {     // 处理 "abc"、""、"  " 等非数字内容 } catch (const std::out_of_range&) {     // 处理 "99999999999999999999" 这类超大数 }
  • 注意:std::stoi 忽略开头空白,但遇到第一个非法字符就停;例如 "123abc" 会成功转成 123,不抛异常
  • 如果需要严格全匹配(不允许尾随字符),得自己检查剩余部分,比如用 std::from_chars 或手动验证

stoi 和 from_chars 哪个更合适

如果你用的是 c++17 及以上,且在意性能和精确控制,std::from_chars 是更好选择:它不抛异常、不依赖 locale、能返回解析结束位置,还能区分“全匹配”和“部分匹配”。

  • stoi:简单场景够用,但开销略大(构造临时对象、异常机制)
  • from_chars:零分配、无异常、支持更多整数类型long long, unsigned),但需手动检查 ecstd::errc)和指针偏移
  • 示例:
    int x; auto [ptr, ec] = std::from_chars(s.data(), s.data() + s.size(), x); if (ec == std::errc{}) {     // 成功,且 ptr 指向解析结束位置     if (ptr == s.data() + s.size()) {         // 全字符串都被消费 → 严格匹配     } }

常见误用:忽略负号或前导零的影响

stoi 默认按十进制解析,支持带符号("-42" 正确转为 -42),也接受前导零("0123" → 123),但不会当成八进制——除非显式传入基底参数 08

立即学习C++免费学习笔记(深入)”;

  • 错误假设:stoi("0123") 得到 83(八进制)→ 实际是 123(十进制)
  • 要按八进制解析,必须写 stoi("0123", nullptr, 8)stoi("0123", nullptr, 0)(自动识别前缀)
  • 十六进制同理:stoi("0xFF", nullptr, 0) → 255;但 stoi("FF", nullptr, 16) 也行
  • 基底传 0 时,"0x""0X""0" 开头会分别触发十六、十六、八进制解析

实际项目里,stoi 的异常路径往往比转换逻辑本身更容易出问题——尤其当错误处理只打印一句日志就继续执行时,后续代码可能基于一个未定义值运行。宁可多写几行 catch,也不要靠“输入肯定合法”这种假设撑住逻辑。

text=ZqhQzanResources