Как эффективно преобразовать только один следующий символ из байтового массива UTF-8?

У меня есть этот код, который работает:

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

куда bp это QByteArray::const_pointer, а также ut максимальная ожидаемая длина кодированной точки Unicode в кодировке UTF-8.
Затем я беру первый QChar c от QString qs,
Похоже, что должен быть более эффективный способ получить только следующее QChar из байтового массива UTF-8 без необходимости преобразования произвольного количества QByteArray в QString а потом получаю только первое QChar,

РЕДАКТИРОВАТЬ Из комментариев ниже ясно, что никто еще не понимает мой вопрос. Итак, я начну с некоторых основ. UTF-8 и UTF-16 — это две разные кодировки мирового стандарта Unicode. Наиболее распространенной и рекомендуемой кодировкой Unicode для передачи через Интернет и текстовыми файлами Unicode является UTF-8, в результате чего каждая кодовая точка Unicode использует от 1 до 4 байтов в кодировке UTF-8. UTF-16, с другой стороны, более удобен для обработки символов внутри программы. Поэтому подавляющее большинство программного обеспечения постоянно выполняет преобразование между этими двумя кодировками. QChar — это более удобное кодирование UTF-16 для всех кодовых точек Unicode от 0x00 до 0xffff, которое охватывает большинство языков и символов, определенных на данный момент и широко используемых. Суррогатные пары используются для более высоких значений кодовой точки Unicode. В настоящее время кажется, что суррогатные пары имеют ограниченную поддержку и не представляют интереса для меня в данном вопросе.

Когда вы читаете текстовый файл в QPlainTextEdit преобразование выполняется автоматически и за кадром. Чтение QString из QByteArray это также может быть сделано автоматически (при условии, что для вашей локали и настроек кодека установлены UTF-8), или они могут быть выполнены явно с помощью toUtf8 () или fromUtf8 (), как в моем коде выше.

Преобразование в другом направлении может быть эффективно сделано неявно (за кадром) или явно с помощью следующего кода:

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

или же

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

где ba это QByteArray а также si является QString::const_iterator, Они делают то же самое (при условии, что кодек установлен в UTF-8). Они оба преобразуют следующее (один) персонаж из QChar указал в пределах QString в результате чего добавляется один или несколько байтов в ba,

Все что я пытаюсь сделать обратное преобразование только для один персонаж в то же время, эффективно. Внутренне это делается для каждого конвертируемого персонажа, и я уверен, что это делается очень эффективно.

Проблема с QString::fromUtf8(p,n) в том, что n это число байтов обрабатывать, а не количество персонажи преобразовать. Следовательно, вы должны учитывать наибольшее количество байтов, которое может быть 3 (или 4, если он фактически обрабатывает суррогатные пары). Поэтому, если все, что вам нужно, это следующий символ, вы должны быть готовы обработать несколько байтов, они преобразуются, а затем отбрасываются, если результат QString с более чем одним персонажем.

Q: Есть ли функция преобразования, которая делает это один персонаж вовремя?

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, он будет возвращать пустую строку.

Как только это будет возможно, результирующая строка будет содержать один декодированный символ Юникода.

Этот цикл максимально эффективен, и запоминая индекс цикла, можно получить следующие символы таким же образом.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]