Next: , Previous: , Up: Sources   [Contents][Index]


4.2 gettext処理のトリガー

すべてのプログラムで、以下で示すようなlocaleデータの初期化の類が必要となります:

int
main (int argc, char *argv[])
{
  …
  setlocale (LC_ALL, "");
  bindtextdomain (PACKAGE, LOCALEDIR);
  textdomain (PACKAGE);
  …
}

PACKAGELOCALEDIRは、config.hかMakefileで提供される必要があります。詳細については、gettextやGNU helloのソースを眺めてみるとよいでしょう。

この場合、LC_ALLの使用は適切ではないでしょう。LC_ALLLC_ALLにはすべてのlocaleカテゴリー、特にLC_CTYPEが含まれます。この後者のカテゴリーは、プログラムのためにctype.hで定義されている、isalnum関数などで処理する文字列クラスを決定することに責任をもっており、入力される文字列の言語によってはうまく動作しません。たとえばソースコードでç(c-cedilla文字)が使用されている場合、このプログラムはFranceでは問題ありませんがU.S.では動作しません。

LC_ALLというlocaleカテゴリーに他のlocaleが使用された場合、scanf関数による数字の解析に問題が生じるシステムもあります。標準では、このような場合は"C"というlocaleとして知られる追加の書式が認識されるでしょう。しかし"C"というlocaleの書式では、数値を受け付けないシステムもあるようです。状況によっては数値の表示が"C"というlocaleなのか、それともlocalのフォーマットかにより認識できないこともあります。これは千単位の桁区切り文字を使用するときに発生します。いくつかのlocale定義ではnational conventionに従い、桁区切り文字として'.'を使用しますが、この文字は"C"というlocaleでは小数点として使用されます。

これらの理由により、上記のコードのLC_ALLの行は、setlocaleによる行に分けることが必要な場合もあります。

{
  …
  setlocale (LC_CTYPE, "");
  setlocale (LC_MESSAGES, "");
  …
}

POSIX互換のすべてのシステムでは、LC_CTYPELC_MESSAGESLC_COLLATELC_MONETARYLC_NUMERICおよびLC_TIMEが利用できます。ISO C準拠のみのシステムも存在し、それらのシステムにはLC_MESSAGESがありませんが、これらの不足にたいする代替は GNU gettextの<libintl.h>と、GNU gnulibの<locale.h>で定義されています。

LC_CTYPEを変更すると、<ctype.h>という標準ヘッダーファイルで定義されている関数、および<string.h><stdlib.h>という標準ヘッダーファイルで定義されているいくつかの関数が影響をうけることに注意してください。これが望ましくない場合(例えばコンパイラーのパーサー)、GNU gnulibのソースディストリビューションにある‘c-ctype’、‘c-strcase’、‘c-strcasestr’、‘c-strtod’、‘c-strtold’モジュールの、C localeでハードコーディングされている代替の関数を使用することができます。

環境に依存したlocaleとC localeを切り替えて使用することもできますが、この方法はsetlocaleの呼び出しが高価であること、広大なプログラムのソース中でlocaleを切り替える場所を決定するのが退屈であること、localeの切り替えがスレッドセーフではないこと等の理由により、通常は行われません。