1

我有这个有效的代码:

QString qs = QString::fromUtf8(bp,ut).at(0);
QChar c(qs[0]);

其中bpaQByteArray::const_pointerut是 UTF-8 编码的 Unicode 代码点的最大预期长度。然后我QChar cQString qs. 似乎应该有一种更有效的方法来简单地QChar从 UTF-8 字节数组中获取下一个,而不必将任意数量的 a 转换QByteArray为 aQString然后只获取第一个QChar.

编辑从下面的评论中,很明显没有人理解我的问题。所以我将从一些基础知识开始。UTF-8 和 UTF-16 是世界标准 Unicode 的两种不同编码。通过 Internet 和 Unicode 文本文件传输的最常见和最受鼓励的 Unicode 编码是 UTF-8,这导致每个 Unicode 代码点在 UTF-8 编码中使用 1 到 4 个字节。另一方面,UTF-16 更方便处理程序内部的字符。因此,绝大多数软件一直在这两种编码之间进行转换。QChar 是从 0x00 到 0xffff 的所有 Unicode 代码点的更方便的 UTF-16 编码,它涵盖了迄今为止定义和常用的大多数语言和符号。代理对用于更高的 Unicode 代码点值。

当您将文本文件读入时QPlainTextEdit,转换会在后台自动完成。QString从 a中读取 aQByteArray也可以自动完成(前提是您的语言环境和编解码器设置为 UTF-8),或者可以使用 toUtf8() 或 fromUtf8() 显式完成,如我上面的代码。

可以使用以下代码隐式(在幕后)或显式有效地完成另一个方向的转换:

    ba += *si; // Depends on the UTF-8 codec

或者

    ba += QString(*si).toUtf8(); // UTF-8 explicitly

哪里ba是 aQByteArray并且siQString::const_iterator。它们的作用完全相同(假设编解码器设置为 UTF-8)。它们都将下一个(一个)字符从QChar指向的字符转换为 a中的字符,QString从而在ba.

我要做的就是一次只对一个字符进行有效的逆变换。在内部,这是为每个被转换的字符完成的,我相信它正在非常有效地完成。

问题QString::fromUtf8(p,n)在于要处理n字节数而不是要转换的字符数。因此,您必须允许最大字节数,可能是 3(如果实际处理代理对,则为 4)。因此,如果您想要的只是下一个字符,您必须准备好处理几个字节,并且如果结果是QString包含多个字符的 a,它们确实会被转换然后被丢弃。

问:是否有一次转换一个字符的转换功能?

4

1 回答 1

1

您想使用QTextDecoder

根据文档,它是:

QTextDecoder 类提供了一个基于状态的解码器。文本解码器使用特定的编解码器将文本从编码文本格式转换为 Unicode。解码器将此格式的文本转换为 Unicode,记住调用之间所需的任何状态。

这里重要的是状态。QString 和 QTextCodec 是无状态的,因此它们从头到尾处理整个字符串。

另一方面,QTextDecoder 允许您一次处理一个字节的字节缓冲区,保持调用之间的状态,以便调用者知道 UTF-8 序列是否仅被部分解码。

例如:

QTextDecoder decoder(QTextCodec::codecForName("UTF-8"));
QString result;
for (int i = 0; i < bytearray.size(); i++) {
     result = decoder.toUnicode(bytearray.constData() + i, 1);
     if (!result.isEmpty()) {
          break; // we got our character !
     }
}

这个循环背后的基本原理是,只要解码器不能解码一个完整的 UTF-8 字符,它就会返回一个空字符串。

只要能够,结果字符串将包含一个解码的 unicode 字符。

这个循环尽可能的高效,通过记忆循环索引,同样可以得到下一个字符。

于 2016-02-11T17:48:25.200 回答