正在用C++从文件中读取Unicode字符

Reading Unicode characters from a file in C++

本文关键字:读取 Unicode 字符 文件 C++      更新时间:2023-10-16

我想逐个字符读取Unicode文件(UTF-8),但我不知道如何逐个字符读取文件。

有人能告诉我怎么做吗?

首先,看看UTF-8是如何编码字符的:http://en.wikipedia.org/wiki/UTF-8#Description

每个Unicode字符都被编码为一个或多个UTF-8字节。在您读取文件中的第一个下一个字节后,根据该表:

(第1行)如果最高有效位为0(char & 0x80 == 0),则表示您的字符。

(第2行)如果三个最高有效位为110(char & 0xE0 == 0xc0),则必须读取另一个字节,并且第一个UTF-8字节(110YYYyy)的第4,3,2位构成Unicode字符的第一个字节(00000YYY),而下一个字节(10xxxxxx)的两个最低有效位(具有6个最低有效位数)构成Unicode字符(yyxxxxx)的第二个字节;您可以使用C/C++的移位和逻辑运算符轻松地进行位运算:

UnicodeByte1 =   (UTF8Byte1 << 3) & 0xE0;
UnicodeByte2 = ( (UTF8Byte1 << 6) & 0xC0 ) | (UTF8Byte2 & 0x3F);

等等…

听起来有点复杂,但如果你知道如何修改这些位,将它们放在正确的位置来解码UTF-8字符串,这并不困难。

UTF-8与ASCII兼容,因此您可以像读取ASCII文件一样读取UTF-8文件。将整个文件读取为字符串的C++方法是:

#include <iostream>
#include <string>
#include <fstream>
std::ifstream fs("my_file.txt");
std::string content((std::istreambuf_iterator<char>(fs)), std::istreambuf_iterator<char>());

生成的字符串具有与UTF-8字节相对应的字符。你可以这样循环:

for (std::string::iterator i = content.begin(); i != content.end(); ++i) {
    char nextChar = *i;
    // do stuff here.
}

或者,您可以以二进制模式打开文件,然后以这种方式移动每个字节:

std::ifstream fs("my_file.txt", std::ifstream::binary);
if (fs.is_open()) {
    char nextChar;
    while (fs.good()) {
        fs >> nextChar;
        // do stuff here.
    }
}

如果你想做更复杂的事情,我建议你看看Qt。我发现它对这类东西很有用。至少,比重症监护室更不痛苦,因为它做了很多实际的事情。

QFile file;
if (file.open("my_file.text") {
    QTextStream in(&file);
    in.setCodec("UTF-8")
    QString contents = in.readAll();
    return;
}

理论上strlib.h有一个函数mblen,shell返回多字节符号的长度。但在我的例子中,它为多字节符号的第一个字节返回-1,并继续它一直返回。所以我写了以下内容:

{
    if(i_ch == nullptr) return -1;
    int l = 0;
    char ch = *i_ch;
    int mask = 0x80;
    while(ch & mask) {
        l++;
        mask = (mask >> 1);
    }
    if (l < 4) return -1;
    return l;
}  

这比研究shell如何使用mblen花费的时间更少。

试试这个:获取文件,然后根据其长度循环文本

伪码:

String s = file.toString();
int len = s.length();
for(int i=0; i < len; i++)
{
    String the_character = s[i].
    // TODO : Do your thing :o)
}