繁体   English   中英

如何在没有wchar_t的情况下在C ++中对UTF-8字符进行解码/编码

[英]How to decode/encode a UTF-8 char in c++ without wchar_t

如标题所示,我试图将UTF-8字符解码/编码为char,但是我想不使用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;
    }

为什么此代码不起作用? 我根本不明白。

编辑:复制+粘贴意大利面...两个不同的var名称

看来您正在测试错误的值。 您的循环正在读取in的值,但是您正在针对名为c某个值进行测试。

当您读其他字符时,您也会出错。 您使用的是某个值length而不是sz 而且您要向整数添加字符(顺便说一句,它不一定是32位),而不是按位或进行移位和组合。

这些都是奇怪的错误。 也许您没有在问题中粘贴实际代码,或者实际上这些值位于函数范围之内。

我还建议重新排列分支,这有点令人费解。 根据您的代码,规则是:

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;

在循环中,让我们修复clength问题,使用大小表避免愚蠢的分支,使用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不同。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM