C string to unicode

Если я хорошо понимаю, можно использовать как строку, так и wstring для хранения текста UTF-8.

В случае символа char символы ASCII занимают один байт, некоторые символы китайского языка — 3 или 4 и т. Д. Это означает, что str[3] не обязательно указывает на 4-го персонажа.

С wchar_t То же самое, но минимальное количество байтов, используемых на символы, всегда равно 2 (вместо 1 для char ), а 3-х или 4-х байтовый широкий символ займет 2 wchar_t ,

Итак, что, если я хочу использовать string::find_first_of() или же string::compare() и т.д. с такой странно закодированной строкой? Это будет работать ? Класс string обрабатывает тот факт, что символы имеют переменный размер? Или я должен использовать их только в качестве пустых байтовых массивов, в этом случае я бы предпочел wchar_t[] буфер.

Если std::string не обрабатывает это, второй вопрос: существуют ли библиотеки, предоставляющие строковые классы, которые могли бы обрабатывать эту кодировку UTF-8 так, чтобы str[3] фактически указывает на 3-й символ (который будет байтовым массивом длиной от 1 до 4)?

Решение

Вы говорите о Юникоде. Unicode использует 32 бита для представления символа. Однако, поскольку это тратит впустую память, есть более компактные кодировки. UTF-8 является одним из таких кодировок. Предполагается, что вы используете байтовые единицы, и отображает символы Юникода в 1, 2, 3 или 4 байта. UTF-16 — это другой, который использует слова в качестве единиц и отображает символы Юникода в 1 или 2 слова (2 или 4 байта).
Вы можете использовать как кодирование, так и строку, и wchar_t. UTF-8 имеет тенденцию быть более компактным для английского текста / чисел.

Некоторые вещи будут работать независимо от используемой кодировки и типа (сравните). Однако все функции, которые должны понимать один символ, будут нарушены. Т.е. 5-й символ не всегда является 5-й записью в базовом массиве. Может показаться, что он работает с некоторыми примерами, но в конечном итоге он сломается.
Строка :: сравнить будет работать, но не ожидайте получения в алфавитном порядке. Это зависит от языка.
string :: find_first_of будет работать для некоторых, но не для всех. Длинная строка, скорее всего, будет работать только потому, что она длинная, в то время как более короткие строки могут быть сбиты с толку выравниванием символов и приводят к очень трудным поискам ошибок.

Читайте также:  Смартфон с усиленной антенной

Лучше всего найти библиотеку, которая будет обрабатывать ее для вас, и игнорировать приведенный ниже тип (если у вас нет веских причин для выбора того или другого).

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

Вы не можете обрабатывать Unicode с помощью std :: string или любых других инструментов из стандартной библиотеки. Используйте внешнюю библиотеку, такую ​​как: http://utfcpp.sourceforge.net/

Вы правы для тех:
…Это означает, что str [3] не обязательно указывает на 4-й символ … используйте их только как фиктивные байтовые массивы без признаков …

Строка C ++ может обрабатывать только символы ascii. Это отличается от строки Java, которая может обрабатывать символы Unicode. Вы можете сохранить результат кодирования (в байтах) китайских символов в строку (символ в C / C ++ — просто байт), но это бессмысленно, поскольку строка просто обрабатывает байты как символы ascii, поэтому вы не можете использовать строковую функцию для ее обработки.
wstring может быть то, что вам нужно.

Есть кое-что, что следует уточнить. UTF-8 — это просто метод кодирования символов Unicode (преобразование символов из / в формат байтов).

у меня есть строка, которая отображает символы в кодировке UTF-8, и я хочу преобразовать ее обратно в Unicode.

на данный момент моя реализация заключается в следующем:

Я играю со словом "déjà" . Я преобразовал его в UTF-8 через этот онлайн, и поэтому я начал тестировать свой метод со строкой "déjÃ" .

к сожалению, с этой реализацией строка просто остается прежней.

4 ответов

таким образом, проблема заключается в том, что значения единиц кода UTF-8 были сохранены как последовательность 16-битных единиц кода в C# string . Вам просто нужно проверить, что каждый блок кода находится в пределах байта, скопировать эти значения в байты, а затем преобразовать новую последовательность байтов UTF-8 в UTF-16.

Читайте также:  Nissan sunny 1992 отзывы

это легко, однако было бы лучше найти первопричину; место, где кто-то копирует кодовые единицы UTF-8 в 16-битные кодовые единицы. Вероятный виновник-кто-то преобразование байтов в C# string использование неверной кодировки. Е. Г. Encoding.Default.GetString(utf8Bytes, 0, utf8Bytes.Length) .

альтернативно, если вы уверены, что знаете неправильную кодировку, которая использовалась для создания строки, и что неправильное преобразование кодировки было без потерь (обычно, если неправильная кодировка является однобайтовой кодировкой), то вы можете просто сделать шаг обратной кодировки, чтобы получить исходные данные UTF-8, а затем вы можете сделать правильное преобразование из UTF-8 байтов:

Если у вас есть строка UTF-8, где каждый байт правильный (‘Ö’ -> [195, 0] , [150, 0]), вы можете использовать следующее:

В моем случае результат DLL также является строкой UTF-8, но, к сожалению, строка UTF-8 интерпретируется с кодировкой UTF-16 (‘Ö’ -> [195, 0], [19, 32]). Таким образом, ANSI’–’, который равен 150, был преобразован в UTF-16’–’, который равен 8211. Если у вас тоже есть этот случай, вы можете использовать следующее:

Если вам это нужно наоборот, см. Utf16ToUtf8. Надеюсь, я смогу помочь.

У меня есть строка, которая отображает UTF-8 закодированные символы

такой вещи нет .Сеть. Класс string может хранить строки только в кодировке UTF-16. Строка в кодировке UTF-8 может существовать только как байт[]. Попытка сохранить байты в строку не приведет к хорошему концу; UTF-8 использует байтовые значения, которые не имеют допустимой кодовой точки Unicode. Содержимое будет уничтожено при нормализации строки. Так что уже слишком поздно, чтобы восстановить строку к тому времени ваш DecodeFromUtf8() начинает работать.

обрабатывать только кодированный текст UTF-8 с байтом[]. И использовать utf8encoding дополнительно.GetString (), чтобы конвертировать его.

что вы, кажется string неправильно декодирован из другой кодировки, вероятно кодовая страница 1252, который является US Windows по умолчанию. Вот как повернуть вспять, не предполагая никаких других потерь. Одна потеря не сразу это non-breaking space (от U+00A0) в конце строки, которая не отображается. Конечно, было бы лучше сначала правильно прочитать источник данных, но, возможно, источник данных был сохранен неправильно, чтобы начать с.

Читайте также:  Как показать все скрытые листы в excel

I have string that displays UTF-8 encoded characters, and I want to convert it back to Unicode.

For now, my implementation is the following:

I am playing with the word "déjà" . I have converted it into UTF-8 through this online tool, and so I started to test my method with the string "déjÃ" .

Unfortunately, with this implementation the string just remains the same.

Where am I wrong?

4 Answers 4

So the issue is that UTF-8 code unit values have been stored as a sequence of 16-bit code units in a C# string . You simply need to verify that each code unit is within the range of a byte, copy those values into bytes, and then convert the new UTF-8 byte sequence into UTF-16.

This is easy, however it would be best to find the root cause; the location where someone is copying UTF-8 code units into 16 bit code units. The likely culprit is somebody converting bytes into a C# string using the wrong encoding. E.g. Encoding.Default.GetString(utf8Bytes, 0, utf8Bytes.Length) .

Alternatively, if you’re sure you know the incorrect encoding which was used to produce the string, and that incorrect encoding transformation was lossless (usually the case if the incorrect encoding is a single byte encoding), then you can simply do the inverse encoding step to get the original UTF-8 data, and then you can do the correct conversion from UTF-8 bytes:

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock detector