如何在C++中将带重音字符转换为ISO-8859-1(Latin-1)编码的十六进制值?
解决ISO-8859-1字符串转十六进制的问题
咱们先搞明白你遇到的问题根源:
- 你输入的字符串大概率是UTF-8编码的——É在UTF-8里是两个字节
0xC3和0x89,而不是ISO-8859-1的单字节0xC9。 - 你的代码里
unsigned(input[i])会触发符号扩展:因为默认char是有符号类型,0xC3作为有符号char是-61,转成unsigned就变成了0xFFFFFFC3,0x89同理变成0xFFFFFF89,所以才会输出那串超长的十六进制。
接下来给你两个解决方案,按需选择:
方案一:直接处理ISO-8859-1编码的输入
如果你的输入已经是ISO-8859-1编码的字符串,只需要修改ToHex函数,避免符号扩展,同时保证每个字节输出两位十六进制:
#include <sstream> #include <iomanip> #include <string> std::string Helper::ToHex(std::string input) { std::stringstream strstream; // 配置输出格式:十六进制、大写、补前导零 strstream << std::hex << std::uppercase << std::setfill('0'); for (unsigned char c : input) { // 先转成无符号字符,再输出,避免符号扩展,每个字节占两位 strstream << std::setw(2) << static_cast<unsigned>(c); } return strstream.str(); }
这样处理后,ISO-8859-1编码的É(单字节0xC9)就会输出"C9",完全符合你的需求。
方案二:先把UTF-8转成ISO-8859-1
如果你的输入是UTF-8编码,需要先转成ISO-8859-1编码的字符串,再用上面的函数处理。注意:ISO-8859-1只能表示Latin-1范围内的字符,超出的字符转换会丢失信息。
这里用C++标准库的std::wstring_convert实现转换(部分编译器可能需要额外配置,比如GCC需要链接-lstdc++fs):
#include <locale> #include <codecvt> #include <string> std::string Utf8ToIso88591(const std::string& utf8_str) { std::wstring_convert<std::codecvt_utf8<char, 0x10ffff, std::consume_header>, char> converter; try { return converter.from_bytes(utf8_str); } catch (const std::range_error& e) { // 处理转换失败的情况,比如输入包含Latin-1以外的字符 return ""; } } // 使用示例: std::string your_input = "É"; // 假设是UTF-8编码 std::string iso_str = Utf8ToIso88591(your_input); std::string hex_result = Helper::ToHex(iso_str); // hex_result 就是 "C9"
最后提醒一句:C++里处理字符串一定要先明确输入的编码格式,不同编码的字节序列差异很大,找对根源问题就好办啦~
内容的提问来源于stack exchange,提问作者zfgo
相关产品推荐
相关产品推荐

