【C++/Java】16进制字符串表示的Unicode字符与UTF8互转

您所在的位置:网站首页 16进制字符表示 【C++/Java】16进制字符串表示的Unicode字符与UTF8互转

【C++/Java】16进制字符串表示的Unicode字符与UTF8互转

2023-08-18 12:15| 来源: 网络整理| 查看: 265

 

问题描述:要把类似 "\x4E00\x6735\x82B1\x1F339" 这样的字符串转换成UTF8编码的可见字符串 "一朵花🌹"

 

先简单说明一下Unicode与UTF8的关系:

Unicode标准可以理解为一个给世界上所有的字符统一编号的字典,一个字符的Unicode码就是一个编号,也仅仅是一个编号而已,并没有规定这个字符具体要怎么编码bit位来存储和发送。

而UTF8就是具体的编码规则,编码规则如下:

Unicode码范围十六进制标量值(scalar value)二进制UTF-8二进制/十六进制注释000000 - 00007F 128个代码00000000 00000000 0zzzzzzz0zzzzzzz(00-7F)ASCII字符范围,字节由零开始七个z七个z000080 - 0007FF 1920个代码00000000 00000yyy yyzzzzzz110yyyyy(C0-DF) 10zzzzzz(80-BF)第一个字节由110开始,接着的字节由10开始三个y;二个y;六个z五个y;六个z000800 - 00D7FF 00E000 - 00FFFF 61440个代码 [Note 1]00000000 xxxxyyyy yyzzzzzz1110xxxx(E0-EF) 10yyyyyy 10zzzzzz第一个字节由1110开始,接着的字节由10开始四个x;四个y;二个y;六个z四个x;六个y;六个z010000 - 10FFFF 1048576个代码000wwwxx xxxxyyyy yyzzzzzz11110www(F0-F7) 10xxxxxx 10yyyyyy 10zzzzzz将由11110开始,接着的字节由10开始

有人可能会疑惑为什么不直接使用Unicode编号来存储和传送字符呢?

主要是因为区分开字符集和编码方案,可使字符的编码存储处理逻辑更清晰、更灵活。

由于Unicode编号只是个数字而已,具体来讲就是short(2字节的Unicode)或者int(4字节扩展Unicode),是定长的, 这对于编号在1字节内的那些常用字符(ASCII字符范围)来说是一种浪费,所以需要UTF8这样的变长编码来节省空间。另一方面,如果是为了更简便快速地进行字符串截断操作,则可考虑使用UTF32这样的定长(4字节)编码。

 

接下来直接上代码

  C++11

Unicode转UTF8

#include #include #include #include #include using namespace std; /** * @description: Unicode码的16进制字符串组成的字符串转UTF8字符 * @param src 例:\x4E00\x6735\x82B1\x1F339 * @return UTF8编码的字符串,例:一朵花🌹 */ string UniHexStrToUtf8(const string& src) { static regex re(R"(\\x([0-9a-zA-Z]{4,5}))"); regex_token_iterator rend; regex_token_iterator it(src.begin(), src.end(), re, 1); wstring_convert conv; string result; while (it!=rend) { result += conv.to_bytes( (char32_t)strtoul((*it).str().c_str(), NULL, 16) ); ++it; } return result; } int main() { cout


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3