У меня есть этот код, который работает:
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: Есть ли функция преобразования, которая делает это один персонаж вовремя?
Вы хотите использовать 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, он будет возвращать пустую строку.
Как только это будет возможно, результирующая строка будет содержать один декодированный символ Юникода.
Этот цикл максимально эффективен, и запоминая индекс цикла, можно получить следующие символы таким же образом.
Других решений пока нет …