std::stoul转换失败时抛std::invalid_argument(格式错误)或std::out_of_range(数值超限),必须用try/catch捕获,且需通过pos参数校验是否全字符串解析完毕。

std::stoul 转换失败时抛什么异常?
它只抛 std::invalid_argument(输入非数字格式)或 std::out_of_range(超出 unsigned long 表示范围),不会返回错误码。没做 try-catch 就崩,尤其处理用户输入或配置文件时很常见。
实操建议:
- 必须用
try/catch包裹,不能靠返回值判断成败 -
std::out_of_range不仅发生在超大数,也可能是负号开头的字符串(如"-123")——stoul会先尝试解析符号,再检查是否能放进unsigned long,结果溢出 - 若需区分“格式错”和“数值超限”,需分别捕获两个异常类型
std::stoul 解析十六进制或八进制字符串怎么写?
靠第三个参数 base 控制进制,不传默认是 10;设为 0 时会按前缀自动识别("0x"→16,"0"→8,否则→10)。
实操建议:
- 显式传
0最安全:std::stoul("0xFF", nullptr, 0)→ 255 - 传
16时不能带"0x"前缀,否则解析停在x处,剩余字符被忽略(std::stoul("0xFF", &idx, 16)中idx指向'x',结果是 0) - 八进制字符串别漏掉前导
0,"777"是十进制,"0777"才是八进制(传0或8都行)
如何获取成功解析到哪一位、跳过空白或校验是否全解析?
第二个参数 pos 是输出型指针,指向第一个未参与转换的字符位置,可用于验证是否“整个字符串都被用了”。
实操建议:
- 声明
std::size_t idx = 0,传&idx进去,调用后检查idx == s.length()确认无残留字符 - 开头空白会被自动跳过(符合 C 标准库行为),但结尾空白不会——
"123abc"解析出 123,idx指向'a';"123 "同样只解析 123,idx指向空格 - 如果业务要求严格全匹配,必须手动校验
idx,不能只看有没有异常
std::stoul 和 std::strtoul 有什么关键区别?
前者是 C++ 封装,后者是 C 函数;核心差异在错误处理和接口设计。
实操建议:
-
std::stoul异常驱动,简洁但无法避免开销;std::strtoul返回0或ULONG_MAX并设errno,适合性能敏感或需精细控制错误分支的场景 -
std::stoul不支持指定 locale,始终按 C locale 解析;std::strtoul可配合setlocale支持千位分隔符等(但实际很少用) - 跨平台时注意:
unsigned long在 Windows(LLP64)和 Linux(LP64)下都是 32 位或 64 位不统一,若需稳定 64 位无符号,应优先考虑std::stoull
真正容易被忽略的是:即使字符串看起来合法,stoul 也可能因 locale 或隐式 base 推导出错;生产环境别省那几行 try/catch 和 pos 校验。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











