c++中如何实现十六进制字符串转整数_c++ stoul函数用法详解【汇总】

13次阅读

stoul(“ff”)会出错是因为默认按十进制解析,遇到非数字字符’f’立即抛出std::invalid_argument异常;c++标准库不支持隐式进制推断,必须显式指定base=16。

c++中如何实现十六进制字符串转整数_c++ stoul函数用法详解【汇总】

直接用 std::stoul 就能转,但必须显式指定进制为 16,否则默认按十进制解析,"ff" 会报错或结果错误。

为什么 stoul("ff") 会出错?

std::stoul 默认按十进制(base = 10)解析字符串。遇到非数字字符(如 'f')立即抛出 std::invalid_argument 异常。它不会自动识别 "0xff" 这类前缀格式——C++ 标准库不支持隐式进制推断。

常见错误现象:

  • stoul("ff") → 抛出 std::invalid_argument
  • stoul("0xff") → 同样失败,因为 '0''x' 在十进制下非法
  • stoul("ff", nullptr, 16) → 正确,显式指定 base = 16

stoul 的三个参数怎么配?

函数原型是:unsigned long stoul(const String& str, size_t* pos = nullptr, int base = 10)。关键在第三参数 base,十六进制必须传 16;第二参数可选,用于获取解析结束位置。

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

实操建议:

  • 总是显式传 16,别依赖默认值
  • size_t idx 捕获解析偏移,验证是否整个字符串都被消费:if (idx != str.Length()) 表示有无效后缀
  • 注意返回类型是 unsigned long,超范围会抛 std::out_of_range
std::string s = "1a3f"; size_t idx; try {     unsigned long val = std::stoul(s, &idx, 16);     if (idx == s.length()) {         // 解析完整,val == 6719     } } catch (const std::exception& e) {     // 处理 invalid_argument 或 out_of_range }

std::stoistd::stoull 有什么区别

核心差异在返回类型和取值范围,不是功能逻辑:

  • std::stoi → 返回 int,通常 32 位,最大约 2^31-1"ffffffff" 在多数平台会溢出
  • std::stoul → 返回 unsigned longwindows 下常为 32 位,linux/macOS 通常 64 位;需查 sizeof(unsigned long)
  • std::stoull → 返回 unsigned long long,保证至少 64 位,适合长十六进制串(如哈希值)

性能和兼容性影响:三者底层解析逻辑一致,无显著性能差;但跨平台时 unsigned long 位宽不统一,处理超过 4 字节的十六进制串应优先选 stoull

要不要自己写解析?

绝大多数场景不需要。标准库 stoul 已高度优化,且正确处理前导空格、符号(十六进制不支持负号)、溢出异常。唯一例外是:你需要容忍非法字符后缀(如 "ffabc" 只取前两位),此时可手动遍历 + std::isdigit/std::isxdigit,但要自行管理进制转换和溢出检查。

容易被忽略的点:十六进制字符串不区分大小写("FF""ff" 都合法),stoul 原生支持;但如果你手写循环,记得用 std::tolower 或直接比较大小写字符。

text=ZqhQzanResources