C++的stringstream能否将"0x123"类十六进制字符串转换为int类型?
现象确认
你观察到的情况属实。std::stringstream默认使用十进制规则解析整数,解析"0x123"时,第一个字符'0'是合法十进制数字,第二个字符'x'不属于十进制数字范围,会直接终止解析流程,因此最终得到的数值是0,后续的"x123"内容会被直接忽略。
正确转换方案
下面提供三种常用的可行方案:
- 方案1:给stringstream添加
std::hex操纵符
在读取整数前为流设置十六进制解析规则即可,std::hex会自动适配0x前缀:
#include <iostream> #include <sstream> #include <string> int main() { std::string s1 = "0x123"; int c; std::stringstream ss; ss << s1; ss >> std::hex >> c; std::cout << c << std::endl; // 输出291,即0x123对应的十进制值 }
如果后续需要用同一个流解析十进制数值,需要添加std::dec重置解析规则。
- 方案2:使用C++11新增的
std::stoi函数
该方法代码更简洁,第三个参数指定解析基数时填0,会自动识别字符串的进制前缀:0开头识别为八进制,0x开头识别为十六进制,否则识别为十进制:
#include <iostream> #include <string> int main() { std::string s1 = "0x123"; int c = std::stoi(s1, nullptr, 0); std::cout << c << std::endl; // 输出291 }
如果确认输入都是十六进制格式,也可以直接将第三个参数填为16,无需依赖前缀判断。
- 方案3:兼容旧标准的C风格
strtol函数
如果需要兼容C++11之前的标准,可以使用标准库的strtol函数,同样支持自动识别进制前缀:
#include <iostream> #include <string> #include <cstdlib> int main() { std::string s1 = "0x123"; int c = static_cast<int>(strtol(s1.c_str(), nullptr, 0)); std::cout << c << std::endl; // 输出291 }
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

