如何在C++中将无符号整数转为无千位分隔符的十六进制字符串
问题
为存储按钮文本颜色,定义了uint32_t类型变量textColor,值为0xF5CE52(十进制16109138)。需要将其转为十六进制字符串插入到字符串中,但使用stringstream转换时,十六进制字符串出现了千位分隔符,无法解决。
使用的转换代码:
uint32_t textColor = 0xF5CE52; stringstream btnColorHex; btnColorHex << uppercase << setfill('0') << setw(6) << hex << textColor;
打印代码:
cout << "btnColorHex.str() - " << btnColorHex.str() << endl;
输出结果:
btnColorHex.str() - F5C.E52
注:系统区域设置为荷兰格式,使用.作为千位分隔符,,作为小数分隔符。
预期输出应为:
btnColorHex.str() - F5CE52
曾通过事后移除字符串中的.解决,但在使用,作为千位分隔符的美式格式系统上失效。尝试将uint32_t强制转为unsigned int,问题依旧。可以使用C语言的sprintf()函数规避,但想了解是否有标准C++解决方案。
问题:是否有C++方法将无符号整数格式化为无千位分隔符的十六进制字符串?
标准C++解决方案
问题根源是当前系统区域设置会对数值格式化自动添加千位分隔符,以下是两种符合标准C++规范的解决方式:
方式一:绑定C语言默认区域设置
直接为stringstream绑定C locale,该区域设置不会添加任何千位分隔符,代码示例:
#include <iostream> #include <sstream> #include <iomanip> #include <locale> int main() { uint32_t textColor = 0xF5CE52; std::stringstream btnColorHex; // 绑定C locale,禁用区域相关的格式化规则 btnColorHex.imbue(std::locale("C")); btnColorHex << std::uppercase << std::setfill('0') << std::setw(6) << std::hex << textColor; std::cout << "btnColorHex.str() - " << btnColorHex.str() << std::endl; return 0; }
方式二:自定义无分隔符的数值格式化规则
如果不想改变全局或局部区域设置,可以自定义一个不添加千位分隔符的numpunct facet,注入到当前locale中:
#include <iostream> #include <sstream> #include <iomanip> #include <locale> struct NoSeparatorNumPunct : public std::numpunct<char> { protected: virtual char do_thousands_sep() const override { // 返回空字符,禁用千位分隔符 return '\0'; } virtual std::string do_grouping() const override { // 返回空字符串,表示无分组规则 return ""; } }; int main() { uint32_t textColor = 0xF5CE52; std::stringstream btnColorHex; // 注入自定义的numpunct facet到当前locale btnColorHex.imbue(std::locale(btnColorHex.getloc(), new NoSeparatorNumPunct())); btnColorHex << std::uppercase << std::setfill('0') << std::setw(6) << std::hex << textColor; std::cout << "btnColorHex.str() - " << btnColorHex.str() << std::endl; return 0; }
两种方式都能稳定输出无千位分隔符的十六进制字符串,且不受系统区域设置影响。
内容的提问来源于stack exchange,提问作者BoredStudent
相关产品推荐
相关产品推荐

