c++中如何将字符串转换为整数_c++ string转int方法【详解】

13次阅读

最稳妥用std::stoi但需处理异常;std::strtol更可控,支持全匹配检查和进制指定;手写解析适用于无异常环境或定制规则;注意locale影响及双重溢出检查。

c++中如何将字符串转换为整数_c++ string转int方法【详解】

直接用 std::stoi 最稳妥,但必须处理异常;手写解析或 std::strtol 更可控,尤其面对非法输入、溢出或前导空格时。

std::stoi 适合简单场景,但不捕获细节错误

std::stoi 是最常用的转换函数,语法简洁:

std::String s = "123"; int n = std::stoi(s);

但它有三个关键限制:

  • 遇到非数字字符(如 "123abc")会截断转换,返回 123,不报错
  • 超出 int 范围时抛出 std::out_of_range 异常,不区分上溢/下溢
  • 对空字符串、纯空格或只有符号(如 "+")直接抛 std::invalid_argument

若业务要求“严格全匹配”,需额外检查转换后是否消耗了整个字符串:

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

size_t pos; int n = std::stoi(s, &pos); if (pos != s.length()) {     // 有未解析的尾部字符,视为失败 }

std::strtol 更健壮,能精确控制解析行为

std::strtol 是 C 风格函数,但 c++ 中仍推荐用于需要精细控制的场景。它返回 long,支持指定进制,并通过 endptr 指示解析终点:

const char* cstr = s.c_str(); char* endptr; long val = std::strtol(cstr, &endptr, 10);

使用时注意:

  • endptr == cstr 表示一个有效数字都没识别到(如空串、纯空格)
  • *endptr != '' 表示存在尾部非法字符(如 "42x"
  • 需手动检查 val 是否在 INT_MININT_MAX 内,再转为 int,否则可能静默溢出
  • 支持进制参数:std::strtol("ff", nullptr, 16)255

手写解析适用于嵌入式、无异常环境或自定义规则

当不能依赖 STL 异常,或需跳过前导空格、接受 '_' 分隔符、限制位数等定制逻辑时,手写更可靠。核心逻辑包括:

  • 跳过开头空白(std::isspace
  • 记录符号位,移动指针
  • 逐字符判断 c >= '0' && c ,累加:num = num * 10 + (c - '0')
  • 每步检查溢出:if (num > (INT_MAX - digit) / 10)
  • 最后乘符号返回

优点是零依赖、可预测、易调试;缺点是代码量略增,需覆盖所有边界(如 "-2147483648" 这种恰好等于 INT_MIN 的情况)。

别忽略 locale 和编码问题

std::stoistd::strtol 都依赖当前 C locale 的数字识别规则。默认 "C" locale 下只认 ASCII 数字 '0'–'9';若程序切换过 locale(如设为 "zh_CN.UTF-8"),某些实现可能影响解析行为——尽管实践中极少遇到非 ASCII 数字参与转换,但仍建议显式保持 C locale:

std::locale::global(std::locale("C"));

或者更安全的做法:始终用 .c_str() 提供的 ASCII 字节流调用 strtol,避免 string 内容含多字节 UTF-8 数字(这本身就不符合常规整数表示)。

真正容易被忽略的是:溢出检查必须做两次——一次在 strtol 后判断范围,一次在赋值给 int 前确认值有效;而 stoi 的异常只告诉你“错了”,不告诉你错在哪一环。

text=ZqhQzanResources