如何以某种方式缩短QString,当转换为UTF-8时,它比某个长度短?

时间:2014-10-29 11:39:20

标签: utf-8 qstring

我正在尝试创建一个有效的算法,用于缩短QString,因此当转换为UTF-8时,它将比定义的长度短并且仍然是有效的UTF-8。

  • 输入
    • QString text - 包含所有可能字符的字符串 - 未指定最大长度
    • int limit - 以utf-8
    • 编码的输出的最大长度
  • 输出
    • QByteArray输出 - utf-8中的原始文本短于限制。
  • 例1:
    • text =“你好吗?”
    • limit = 5
    • output =“如何”
  • 例2:
    • text =“Какдела?”
    • limit = 5
    • 输出=“Ка”
      • d0 9a d0 b0 - 包括“к”已超出限制,包括d0将导致无效的utf-8字符串。

首先我们从以下代码开始,但是这可能会在中间删除UTF-8字符,这是不可接受的:

QByteArray output = text.toUtf8().left(limit);

比我们开发的正确算法有效,但是非常难看且效率不高:

QString tmp = input;
while (tmp.toUtf8().size() > limit)
    tmp.chop(1);
QByteArray output = tmp.toUtf8();
  • 有更好的方法,怎么做?
    • 如果是,请分享代码吗?
    • 如果没有,为什么?

1 个答案:

答案 0 :(得分:1)

除非您想编写自己的UTF-8转换例程,否则以下方法应该是最佳的。它依赖于UTF-8序列中的连续字节在0x80-0xBF范围内的事实。从限制向后,它试图找到可以安全地拆分字符串的第一个起始字节。

QByteArray output = tmp.toUtf8();
if (output.size() > limit) {
    int truncateAt = 0;
    for (int i = limit; i > 0; i--) {
        if ((output[i] & 0xC0) != 0x80) {
            truncateAt = i;
            break;
        }
    }
    output.truncate(truncateAt);
}

由于UTF-8字节序列不超过4个字节,因此不应该进行4次以上的循环迭代才能找到正确的位置。