Определить, содержит ли байтовый массив строку ANSI или Unicode? - PullRequest
2 голосов
/ 04 октября 2011

Скажем, у меня есть функция, которая получает байтовый массив:

void fcn(byte* data)
{
...
}

Кто-нибудь знает надежный способ для fcn () определить, является ли data строкой ANSI или Unicode?string?

Обратите внимание, что я намеренно НЕ передаю аргумент длины, все, что я получаю, это указатель на массив.Аргумент длины был бы большой помощью, но я не получаю его, поэтому я должен обойтись без.

В этой статье упоминается OLE API, который, очевидно, делает это, но, конечно, они не говорят вам, ЧТОAPI-функция: http://support.microsoft.com/kb/138142

1 Ответ

5 голосов
/ 04 октября 2011

Сначала слово по терминологии.Нет такой вещи как строка ANSI;Есть строки ASCII, которые представляют кодировку символов.ASCII был разработан ANSI, но они не являются взаимозаменяемыми.

Кроме того, нет такой вещи, как строка Unicode.Существует кодировки Unicode , но они являются только частью самого Unicode.

Я буду считать, что под «строкой Unicode» вы подразумеваете «кодированную последовательность кодов UTF-8».А под строкой ANSI я предполагаю, что вы имеете в виду ASCII.

Если так, то каждая строка ASCII также является строкой UTF-8, по определению кодировки UTF-8.ASCII определяет только символы размером до 0x7F, и все кодовые единицы UTF-8 (байты) до 0x7F означают то же самое, что и в ASCII.

Таким образом, вы должны учитывать другие 128 возможных значений.Это ... сложно.

Единственная причина, по которой вы задали бы этот вопрос, это отсутствие контроля над кодированием ввода строки.И поэтому проблема в том, что ASCII и UTF-8 не единственно возможные варианты.

Например, есть Latin-1.Есть много строк, которые закодированы в Latin-1, который берет другие 128 байтов, которые не использует ASCII, и определяет символы для них.Это плохо, потому что другие 128 байтов будут конфликтовать с кодировкой UTF-8.

Есть также кодовые страницы .Многие строки были закодированы для определенной кодовой страницы;это особенно относится к Windows.Для их декодирования необходимо знать, над какой кодовой страницей вы работаете.

Если вы находитесь в ситуации, когда вы уверены , что строка является либо ASCII (7-битной, старший бит всегда0) или UTF-8, тогда вы можете сделать определение легко.Либо строка является ASCII (и, следовательно, также UTF-8), либо один или несколько байтов будут иметь старший бит, установленный в 1. В этом случае вы должны использовать Логика декодирования UTF-8 .

Если вы действительно не уверены в том, что это всего лишь возможностей, вам нужно будет сделать немного больше.Вы можете проверить данные, пытаясь запустить их через декодер UTF-8.Если он встречается с недопустимой кодовой последовательностью, то вы знаете, что это не UTF-8.Проблема заключается в том, что теоретически возможно создать строку Latin-1, которая является технически допустимой UTF-8.Вы в некотором роде в этот момент.То же самое касается строк на основе кодовой страницы.

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

...