ロケールの使い方

こんにちは、めのんです!

延び延びになっていたロケールの解説をそろそろしようと思います。
といっても、そんなに大した内容は無いので簡単に済ませますね。

文化圏固有操作

Cでは文化圏固有操作(localization)のために「ロケール」という概念を用います。
ロケールそのものについてはPHPにもありますので割愛します。

ロケール関連の関数や型の宣言・定義は「locale.h」ヘッダで行われます。

setlocale関数

「setlocale関数」はPHPにも同名の関数がありますし、使い方もほとんど変わりません。
Cのsetlocale関数は2引数しか取れませんので、それぐらいの違いです。

setlocale関数は「locale.h」ヘッダで次のように宣言されます。

char *setlocale(int category, const char *locale);

categoryに指定できる値もPHPも基本的には同じで、LC_ALLなど「LC_」で始まるマクロ名を使用します。
それらのマクロは「locale.h」ヘッダで定義されています。
ただし、LC_MESSAGEはCの標準規格では定義されていませんので注意してください(POSIXでは定義されています)。

デフォルトのロケールは”C”です。
これはPHPでも同じだと思うのですけど、PHPの公式ドキュメントをちょっと調べた限りでは記載されていないように思います。
いずれにしてもデフォルトは”C”ロケールです。

Cの標準規格で使用可能なことが保証されているのは、”C”と””だけです。
空文字列(””)をlocaleに指定した場合はその文化圏に固有の動作になります。
これもPHPと同じですね。

現在設定されているロケールを取得する方法はCとPHPで若干異なります。
PHPではlocaleに”0″を指定しますがCではNULLを指定します。
PHPでNULLを指定すると””を指定したのと同じ意味になりますので、このあたりは紛らわしいの十分注意してください。

localeconv関数

「localeconv関数」もPHPに同名の関数がありますし、使い方もほぼ同じです。
ただし、PHPでは配列を返しますがCでは構造体へのポインタを返します。

localeconv関数は「locale.h」ヘッダで次のように宣言されています。

struct lconv *localeconv(void); 

返却値のポインタの参照先はlocalecnv関数を呼び出すたびに上書きされますので注意してください。

「lconv構造体」のメンバは、PHPのlocalecnv関数が返す配列のキー名とほぼ同じものがそろっています。
なお、メンバの順序は規格では規定されていませんので、必ずしもこの順序になっていません。

struct lconv
{
  char *decimal_point;      // "."
  char *thousands_sep;      // ""
  char *grouping;           // ""
  char *mon_decimal_point;  // "" 
  char *mon_thousands_sep;  // ""
  char *mon_grouping;       // ""
  char *positive_sign;      // ""
  char *negative_sign;      // ""
  char *currency_symbol;    // ""
  char frac_digits;         // CHAR_MAX
  char p_cs_precedes;       // CHAR_MAX
  char n_cs_precedes;       // CHAR_MAX
  char p_sep_by_space;      // CHAR_MAX
  char n_sep_by_space;      // CHAR_MAX
  char p_sign_posn;         // CHAR_MAX
  char n_sign_posn;         // CHAR_MAX
  char *int_curr_symbol;    // ""
  char int_frac_digits;     // CHAR_MAX
  char int_p_cs_precedes;   // CHAR_MAX
  char int_n_cs_precedes;   // CHAR_MAX 
  char int_p_sep_by_space;  // CHAR_MAX
  char int_n_sep_by_space;  // CHAR_MAX
  char int_p_sign_posn;     // CHAR_MAX
  char int_n_sign_posn;     // CHAR_MAX 
};

コメントは”C”ロケールのときの値です。
decimal_pointを除いてchar*型のメンバは””、char型のメンバはCHAR_MAXになります。
char型のメンバの値がCHAR_MAXの場合はそのメンバが使われていないことを意味します。

ほとんどのメンバはPHPにもあるのもものなので解説は省略しますが、CとPHPで異なるメンバだけ解説しておきます。

通貨に関するメンバ、p_sep_by_space、n_sep_by_space、int_p_sep_by_space、およびint_n_sep_by_spaceは、PHPではTRUEかFALSEしか設定されませんが、Cでは0、1、2の3種類の値が設定されます。
それぞれの値の意味は次のようになります。

  1. 通貨記号と値は空白によって区切らない。
  2. 通貨記号と符号文字列が隣接していれば,一つの空白がそれらと値とを区切る。そうでなければ一つの空白が通貨記号と値とを区切る。
  3. 通貨記号と符号文字列が隣接していれば,一つの空白がそれらを区切る。そうでなければ一つの空白が符号文字列と値とを区切る。

最後の2つはPHPにはありません。

int_p_sign_posn
国際様式で書式化された負でない金額数量において,positive_signの位置を示す値。
int_n_sign_posn
国際様式で書式化された負でない金額数量において,negative_signの位置を示す値。

値の意味はp_sign_posnやn_sign_posnと同じと考えてください。


今回の解説は以上となります。
ロケールについてはいろんなところで登場しますので、個別の解説はその都度行っていきたいと思います。
それでは。