Что значит "программа правильно написана" ?

    "Правильно" написанная программа с использованием POSIX locale не дожна зависить от способа кодирования ("кодировки") символов. Такая программа нигде не привязана к 7-ми битным ASCII символам, и пользуется стандатрными библиотечными (API) функциями localeisalpha(), isupper(), isxxx() и tolower()/toupper() не полагаясь, что Upper=Lower+0x20 и т.д.  Конструкции, подобные этой также недопустимы :

      if (c >= 'A' && c <= 'Z') { ...

Пользуйтесь :

      if (isalpha(c) && isupper(c)) { ...

    Как правило, национальные алфавиты расположены начиная с кода 0x80, поэтому для совместимости со старыми реализациями locale можно объявить все символы как unsigned char, например ключом компилятора (для gcc -funsigned-char) или явно.

    Хорошо написанная программа должна быть польностью 8-бит прозрачна. Например пометка   удаленного файла в MS-DOS кодом 0x0E5 - не очень правильное решение. Или знаменитая буква "Н" в редакторе GoldEd.

    Также не следует забывать, что тип char языка C на самом деле практически означает byte и никак не задает кодировку этого символа. Если вы планируете работу вашей программы в многоязычном окружении, неплохо бы предусмотреть атрибут charset у строк символов char *. Или переходить на UNICODE (wchar_t) в качестве внутренней кодировки.

 

    Во-вторых, программа должна явно начинаться с вызова setlocale(LC_ALL,"") (такая форма вызова означает, что всем категориям локализации одновременно будет присвоено значение переменной окружения LANG). До этого момента программа работает в локализации POSIX (С).

ПРИМЕЧАHИЕ: Во FreeBSD можно вылечить некоторые программы, в которых забыт вызов setlocale() путем задания строки окружения :
$ export ENABLE_STARTUP_LOCALE=""
тогда setlocale(LC_ALL,"") будет вызываться автоматически при старте программ (без их перекомпиляции).
   В Linux libc такого нет (пока?) и по умолчанию всегда включено "C" или "POSIX". Однако можно пересобрать Linux libc, указав другое значение по умолчанию. Но следует отметить, что такое решение будет противоречить стандарту, по которому программа стартует в POSIX (до первого вызова setlocale()).

    Для получения locale-зависимой информации следует пользоватся данными структуры lconv, которые можно получить вызовом функции localeconv() . Для получения детальной информации по категориям локализации (описанным в файле <langinfo.h> ) можно пользовться функцией nl_langinfo(). (Эта функция не входит в POSIX, но входит в XPG, и большинство систем ее имеют).

    Для сравнения строк символов следует пользоваться функциями strcoll() и strxfrm() вместо strcmp().

 

    Для полной поддержки NLS весь вывод сообщений пользователю должен происходить c использованием функций NLS и должен быть создан каталог сообщений (message catalog) для данной программы (и данного языка).

    А в заключение, неплохо бы иметь man на разных языках. :-)


Содержание "Locale AS IT IS"


Last change : 30-04-1999


Banner.Novgorod.Ru