gcc, UTF-8 и limit.h - PullRequest
       32

gcc, UTF-8 и limit.h

2 голосов
/ 18 апреля 2010

Моя ОС - Debian, моя локаль по умолчанию - UTF-8, а мой компилятор - gcc.По умолчанию CHAR_BIT в limit.h равен 8, что нормально для ASCII, потому что в ASCII 1 символ = 8 бит.Но поскольку я использую UTF-8, символы могут иметь длину до 32 бит, что противоречит значению по умолчанию CHAR_BIT, равному 8.

Если я изменю CHAR_BIT на 32 в limit.h, чтобы лучше подходить к UTF-8,Я должен сделать, чтобы это новое значение вступило в силу?Я думаю, я должен перекомпилировать GCC?Нужно ли перекомпилировать ядро ​​Linux?Как насчет установленных по умолчанию пакетов Debian, они будут работать?

Ответы [ 5 ]

4 голосов
/ 18 апреля 2010

CHAR_BIT - количество бит в char; никогда, никогда не меняй это. Это не даст желаемого эффекта.

Вместо этого работайте со строками в кодировке UTF-8 char s или используйте строки wchar_t, если вы хотите хранить символы Unicode напрямую. *

* Мелкий шрифт: размер wchar_t также зависит от системы. В Windows с MSVC это всего 16 бит, что достаточно только для базовой многоязычной плоскости. Однако вы можете использовать его с UTF-16, что хорошо сочетается с Windows API. В большинстве других систем wchar_t дает вам полные 32 бита.

3 голосов
/ 18 апреля 2010

Для кодировки UTF-8 не требуется, чтобы символ был 32-битным. UTF-8 - кодирование переменной длины, оно предназначено для 8-битных символов и обратно совместимо с ascii.

Вы также можете использовать wchar_t, который является 32-битным (в Linux), но, как правило, вы не дадите большая добавленная стоимость, потому что обработка Unicode намного сложнее, чем просто управление кодами.

1 голос
/ 18 апреля 2010

C и C ++ определяют char как байт, т. Е. Целочисленный тип, для которого sizeof возвращает 1. Это не должно быть 8 бит, но в подавляющем большинстве случаев это так. ИМХО, это должно было быть с именем byte. Но в 1972 году, когда был создан C, западным пользователям не приходилось иметь дело с многобайтовыми кодировками символов, так что вы могли избежать смешения типов «символов» и «байтов».

Вы просто должны жить с запутанной терминологией. Или typedef это прочь. Но не редактируйте файлы заголовков вашей системы. Если вы хотите использовать символьный тип вместо байтового типа, используйте wchar_t.

Но строка UTF-8 состоит из 8-битных кодовых единиц, поэтому char будет работать просто отлично. Вы просто должны помнить разницу между char и характером. Например, не делайте этого:

void make_upper_case(char* pstr)
{
   while (*pstr != '\0')
   {
      *pstr = toupper(*pstr);
      pstr++;
   }
}

toupper('a') работает как положено, но toupper('\xC3') - бессмысленная попытка прописной половины символа.

1 голос
/ 18 апреля 2010

Я почти уверен, что CHAR_BIT - это количество бит в типе переменной 'char', не максимальное количество бит в любом символе. Как вы заметили, это константа в limit.h, которая не меняется в зависимости от настроек локали.

CHAR_BIT будет равно 8 в любой разумно новой / разумной системе ... не 8-битные слова в наши дни редки:)

1 голос
/ 18 апреля 2010

UTF-8 кодирует 1 символ в несколько байтов.

Кроме того, не редактируйте файлы заголовков вашей системы. (и нет, изменение CHAR_BITS не будет работать, перекомпилируя ядро ​​/ gcc или еще много чего).

...