如何在没有wchar_t的情况下在 c++ 中解码/编码 UTF-8 字符
How to decode/encode a UTF-8 char in c++ without wchar_t
正如标题所述,我正在尝试将 UTF-8 字符解码/编码为字符,但我想在不使用wchar_t等的情况下执行此操作。我想自己做腿部工作。这样我知道我理解它,我显然不理解它,否则它会起作用。我花了大约一个星期的时间玩弄它,只是没有取得进展。
我已经尝试了几种方法,但似乎总是产生不正确的结果。我的最新尝试:
ifstream ifs(FILENAME);
if(!ifs) {
cerr << "Open: " << FILENAME << "n";
exit(1);
}
char in;
while (ifs >> std::noskipws >> in) {
int sz = 1;
if ((in & 0xc0) == 0xc0) //0xc0 = 0b11000000
{
sz++;
if((in & 0xE0) == 0xE0) //0xE0 = 0b11100000
{
sz++;
if((in & 0xF0) == 0xF0) //0xF0 = 0b11110000
sz++;
}
}
cout << sz << endl;
unsigned int a = in;
for(int i = 1; i < sz; i++) {
ifs >> in;
a += in;
}
为什么这段代码不起作用?我根本不明白。
编辑:复制+粘贴意大利面...两个不同的变量名称
您似乎正在测试错误的值。 您的循环正在读取值in
,但您正在针对名为c
的某个值进行测试。
当你读到额外的字符时,你也做错了。 您正在使用一些值length
而不是大概sz
。 而且您正在向整数添加字符(顺便说一下,它不一定是 32 位),而不是与按位 OR 移动和组合。
这些都是奇怪的错误。 也许您没有将实际代码粘贴到问题中,或者您实际上将这些值放在函数的范围内。
我还建议重新排列你的分支,这有点迟钝。 根据您的代码,规则是:
mask | sz
---------+-------
0xxxxxxx | 1
10xxxxxx | 1
110xxxxx | 2
1110xxxx | 3
1111xxxx | 4
您可以定义一个简单的表,以根据上部 4 位选择大小。
int sizes[16];
std::fill( sizes, sizes+16, 1 );
sizes[0xc] = 2;
sizes[0xd] = 2;
sizes[0xe] = 3;
sizes[0xf] = 4;
在你的循环中,让我们修复c
和length
的东西,使用大小表来避免愚蠢的分支,使用istream::get
而不是流输入运算符 (>>
),并以更正常的方式将字符组合成单个值。
for( char c; ifs.get(c); )
{
// Select correct character size (bytes)
int sz = sizes[static_cast<unsigned char>(c) >> 4];
// Construct character
char32_t val = c;
while( --sz > 0 && ifs.get(c) )
{
val = (val << 8) | (static_cast<char32_t>(c) & 0xff);
}
// Output character value in hex, unless error.
if( ifs )
{
std::cout << std::hex << std::fill('0') << std::setw(8) << val << std::endl;
}
}
现在,最后一部分按大端顺序连接字节。 我不知道这是否正确,因为我还没有阅读标准。 但这比仅仅将值加在一起要正确得多。 它还使用有保证的 32 位数据类型,与您使用的unsigned int
不同。
相关文章:
- 无法解码base64+deflate数据
- 正在解码MSVC 32位版本的程序集(作业).没有手术做什么
- 使用已使用 java 编码的 openssl 解码数据
- 如何使用 OpenCV 解码在两个 UWP 应用之间发送的图像字节?
- 错误:(-210:不支持的格式或格式组合)功能'create'中的硬件视频解码器不支持视频源
- 从原始字节解码协议缓冲区(以 C++为单位)
- FFmpeg——使用硬件加速进行视频解码
- 如何从WIC解码器确定自上而下/自下而上?
- 使用公钥加密消息:BER 解码错误
- 在CRC-16 CCITT中将数据从二进制解码为文本,我应该输入一个码字,使用CRC生成器进行编码
- 在 GLFW 窗口中显示 FFMPEG 解码帧
- 如何将 MJPEG 解码为原始 RGB(或 YUV)数据
- 编译时 Base64 解码 C++
- 解码H264流时如何跳过帧?
- 无法在 HEVC 解码器上设置输出类型 IMFTransform
- pyserial arduino 字节阵列解码问题
- 将帧从 h264 流解码到 OpenCV Mat
- 连接无线电流和 MP3 解码器
- 将数据包从C++服务器发送到NodeJs服务器时出现MessagePack解码错误
- h264_cuvid编解码器未找到