2014-10-24 4 views
4

Этот вопрос:C: символ против неподписанные символ для текстовых данных не-ASCII

What is an unsigned char?

делает большую работу по обсуждению полукокса против неподписанные символ против подписал полукокса в C.

Однако он не касается непосредственно того, что должно использоваться для текста, отличного от ASCII. Таким образом, если у меня есть массив байтов, который представляет текст в некотором произвольном наборе символов, например UTF-8 или Big5 (или иногда ASCII), следует ли использовать массив char или unsigned char?

Я склоняюсь к использованию полукокса, потому что в противном случае НКА дает мне предупреждения о знаковости указателей, когда массив является ASCII, и я использую STRLEN. Но я хотел бы знать, что правильно.

+0

Да, принятый ответ правилен в этом отношении. И строковый тип C представляет собой последовательность байтов с не-NUL, заканчивающихся NUL-байтом, неопределенной кодировки, хотя использовать UTF-8, если у вас есть какой-либо выбор вообще. – Deduplicator

+1

За исключением UTF-8, вы не хотите использовать strlen, потому что могут быть внутренние NUL. Во всяком случае, это огромная тема. Для Unicode я предлагаю http://site.icu-project.org/ –

+1

@Deduplicator. Прочтите более внимательно: ** За исключением ** UTF-8, ... могут быть внутренние NUL. И то, что я имел в виду, это то, что OP упоминает: Big5 и т. Д. Конечно, UTF-16 и UTF-32 могут также содержать внутренние NUL, так что да, то, что я написал, относится к ним * к *. –

ответ

2

Использовать нормальный символ для представления символов. Использовать подписанный символ, если требуется целочисленный тип со знаком, который охватывает значения от -127 to +127. Используйте unsigned char для использования целочисленного типа без знака, который имеет диапазон значений от 0 to 255.

+1

Технически 'uint8_t' следует использовать для последнего (что даст ошибку компилятора, если вы на платформе, которая не поддерживает 8-битные символы) –

+1

Это ничего не говорит (и совсем немного) чем ссылка, предоставленная ОП. т. е. это не ответ на заданный вопрос и даже не отражает, что существует такой вопрос. Ошеломляюще, что у него появилось два оборота. –

2

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

Чтобы ответить на него напрямую, большинство реализаций используют «байт» в качестве основного буфера. В этих условиях стандартный uint8_t typedef - ваш лучший выбор. Это связано прежде всего с тем, что большинство наборов символов используют переменное количество байтов для хранения символов, поэтому отдельная обработка байтов имеет важное значение в процессе кодирования и декодирования. Это также упрощает преобразование между различными «endianess».

В общем случае неправильно использовать strlen на любом другом, кроме ASCII-кодировании или других однобайтовых кодовых страницах (диапазон 0-255). Это, безусловно, неверно для любого многобайтового кодирования, такого как Big5, UTF-8/16 или Shift-JIS.

+1

Как 'strlen()' менее безопасен для UTF-8 и ASCII? Оба имеют код 0. C простой использует код 0 (ASCII NUL) как завершающий символ, тем самым запрещая строку C с символами NULL ASCII. Код может одинаково использовать Unicode 0 (закодированный в UTF-8 как один 0 байт) в качестве символа завершения. Не то, чтобы я одобрял строки с завершенным номером, но не вижу большой озабоченности использованием 'strlen()' в строковой группе UTF-8 кодированных символов Unicode. – chux

+1

@chux UTF-8 не является одиночной кодировкой символов. Он сообщит о некорректном количестве символов. Может быть, «безопасный» был не лучшим словом. –

+3

Верно, что 'strlen()' не будет сообщать количество символов Юникода, но будет безопасно сообщать правильное количество символов 'char', используемых в кодировке UTF-8, в предположении оканчивания 0. – chux

Смежные вопросы