「6.7 複数バイト文字とワイド文字」 では、標準ライブラリの国際化を紹介しました。この節では、国際化の影響を受けるライブラリ関数について説明し、これらの機能を利用するにはどのようにプログラムを書けばいいかのヒントを提供します。この節では、1990 ISO/IEC C 規格に関する国際化についてのみ説明します。1999 ISO/IEC C 規格には、この節で説明する国際化のサポートについて大幅な拡張機能はありません。
C プログラムは常に、現在のロケール (国、文化、および言語に適切な規約を記述した情報の集まり) を持っています。ロケールは文字列の名前を持っています。標準化されたロケール名は、"C" と "" の 2 つだけです。どのプログラムも "C" ロケールから始まります。つまり、すべてのライブラリ関数は従来どおりに動作します。"" ロケールは、各処理系がプログラムの呼び出しに最適であると推測する規約セットです。"C" と "" の動作は同じになることもあります。ほかのロケールは各処理系によって提供されます。
実用性と便宜上の目的により、ロケールはカテゴリに分類されます。プログラムは、ロケール全体を変更することも、1 つまたは複数のカテゴリを変更することもできます。一般的に各カテゴリは、ほかのカテゴリが影響を与える関数とは関係なく、複数の関数に影響を与えます。したがって、一時的に 1 つのカテゴリを変更することにも意味があります。
setlocale() 関数は、プログラムのロケールとのインタフェースです。一般的に、国の規約を呼び出して使用するプログラムは、プログラムの実行パスの前のほうで、次のような呼び出しを行わなければいけません。
#include <locale.h> /*...*/ setlocale(LC_ALL, ""); |
これは、プログラムの実行パスの前のほうで行います。プログラムの実行パスの最初の部分 LC_ALL は 1 つのカテゴリではなく、ロケール全体を指定するマクロであるため、この呼び出しによって、プログラムの現在のロケールが適切なローカルバージョンに変更されます。次に、標準的なカテゴリを示します。
LC_COLLATE |
ソート情報 |
LC_CTYPE |
文字分類情報 |
LC_MONETARY |
通貨の出力情報 |
LC_NUMERIC |
数値の出力情報 |
LC_TIME |
日付と時刻の出力情報 |
前述の任意のマクロを setlocale() への最初の引数として渡すことによって、そのカテゴリを指定できます。
setlocale() 関数は、特定のカテゴリ (または、LC_ALL) に対する現在のロケールの名前を返します。2 番目の引数がヌルポインタの場合は、照会専用として機能します。したがって次のようなコードを使用すると、制限された期間だけロケール (または、その一部) を変更できます。
#include <locale.h> /*...*/ char *oloc; /*...*/ oloc = setlocale(LC_category, NULL); if (setlocale(LC_category, "new") != 0) { /* use temporarily changed locale */ (void)setlocale(LC_category, oloc); } |
ほとんどのプログラムではこの機能は必要ありません。
変更が適切で可能である場合、既存のライブラリ関数はロケールに依存する動作を含むように拡張されました。これらの関数は、次の 2 つのグループに分類できます。
ctype.h ヘッダーで宣言される関数 (文字の分類と変換)
数値を出力可能な形式から内部的な形式に (または、その逆に) 変換する関数 (printf() や strtod() など)
すべての ctype.h 述語関数 (isdigit() と isxdigit() を除く) は、現在のロケールの LC_CTYPE カテゴリが "C" 以外の場合に、追加の文字に対してゼロでない (真の) 値を返すことができます。スペイン語ロケールでは isalpha(’ñ’) は真になります。同様に、文字変換関数 tolower() と toupper() は、isalpha() 関数で識別される特別な英字を適切に処理できます。ctype.h 関数は、ほとんどの場合、文字引数による索引付きテーブル検索を使用して実装されるマクロです。これらの関数の動作を変更するには、テーブルを新しいロケールの値に再設定します。したがって、パフォーマンスに影響はありません。
出力可能な浮動小数点値を書き込んだり解釈したりする前述の関数は、現在のロケールの LC_NUMERIC カテゴリが "C" 以外の場合に、ピリオド (.) 以外の小数点文字を使用するように変更できます。千単位区切り型文字で数値を出力可能な形式に変換するための規定はありません。出力刷可能な形式から内部的な形式に変換するときにも、実装では、"C" 以外のロケールの場合に、このような追加の形式を受け入れることが許可されています。小数点文字を使用する関数は、printf() と scanf() のグループ、atof()、および strtod() です。実装での定義を拡張できる関数は、atof()、atoi()、atol()、strtod()、strtol()、strtoul()、および scanf() のグループです。
新しい標準関数として、特定のロケールに依存する機能が追加されました。ロケール自身を制御する setlocale() 以外にも、ANSI/ISO C 規格には次の新しい関数が導入されました。
localeconv() |
数値/通貨の規約 |
strcoll() |
2 つの文字列の照合順序 |
strxfrm() |
照合のために文字列を変換する |
strftime() |
日付と時刻の形式を決定する |
さらに、複数バイト関数 mblen()、mbtowc()、mbstowcs()、wctomb()、および wcstombs() があります。
localeconv() 関数は、現在のロケールの LC_NUMERIC と LC_MONETARY カテゴリに適切な、書式化された数値および通貨の情報に便利な情報を含む構造体へのポインタを返します。この関数は、動作が複数のカテゴリに依存する唯一の関数です。数値の場合、構造体は、小数点文字、千単位区切り文字、および区切り文字を置く場所を記述します。通貨値を書式化する方法を記述する構造体のメンバーは、ほかにも 15 個あります。
strcoll() 関数は、strcmp() 関数と似ていますが、現在のロケールの LC_COLLATE カテゴリに従って、2 つの文字列を比較するところが異なります。strxfrm() 関数は、変換後の 2 つの文字列を strcmp() に渡すと、変換前の 2 つの文字列を strcoll() に渡した場合に返される順番と似た順番が返されるように、文字列を別の文字列に変換します。
strftime() 関数は、struct tm に値を持つ sprintf() で使用される書式化と似た書式化と、さらに、現在のロケールの LC_TIME カテゴリに依存する日付と時刻の書式を提供します。この関数は、UNIX System V Release 3.2 の一部としてリリースされた ascftime() 関数に基づいています。。