プログラムの間違ったロケール設定を修正しようとするのは間違った場所です。環境に適切なロケールを設定し、次のようにコードでこの値を使用する必要があります。
setlocale(LC_ALL, "");
これは、マンページに次のように記載されています。
メイン プログラムの起動時に、移植可能な "C" ロケールがデフォルトとして選択されます。以下を呼び出すことにより、プログラムをすべてのロケールに移植可能にすることができます。
setlocale(LC_ALL, "");
編集:
最後のスクリーンショットを見ると、入力の読み取り中に何かが混乱しているようです。
ケース 1: ( への呼び出しがないものsetlocale
)
……あんまり面白くない。(デフォルトの) "C" ロケールのように、たとえ正しい結果を生成するように見えても、文字 U+00-U+7E だけが含まれます。値 0x9F はコード ページ 825 (参照: http://de.wikipedia.org/wiki/Codepage_852 ) で、Unicode 文字 'LATIN SMALL LETTER C WITH CARON' (U+010D) をエンコードしますč
。
生の値を前後に渡すと、同じバイトが端末に再度書き込まれた場合に同じ出力が生成されることに大きな驚きはありません。
ケース 2:
...ちょっと面白そうです。値 0x17a は、Unicode 文字 'LATIN SMALL LETTER Z WITH ACUTE' (U+017A) の UTF-16 エンコードでありź
、スクリーンショットに示されている出力と完全に一致します。fputsw はこれを端末エンコーディングに正確にマッピングしているように見えるため、入力が適切に読み取られていないことが問題のようです。
変更を行った後に何も混乱していないことを確認するために、次のようなコードを実行していますか?
#include <stdio.h>
#include <locale.h>
int main () {
wchar_t query[64];
setlocale (LC_ALL, "");
if (fgetws(query, 64, stdin) == NULL)
return -1;
fputws(query, stdout);
putchar('\n');
return 0;
}
編集:
ロケール設定の確認
あなたのテストについて最も興味深いことの1つに言及するのを忘れていましź
た0x9f
.コードページ 1250 で「生の」文字コード) を使用すると報告されます。
どういうわけか、fgetws はコードページ 825 ではなくコードページ 1250 を使用して文字コードを解釈するようです。
私にとっては、ロケール設定がどういうわけか混乱していることに問題があるようです。おそらく、次のコードを実行して、どのロケールが報告されるかを確認する必要があります。
#include <locale.h>
#include <stdio.h>
int main (int argc, char *argv[]) {
char *locale;
setlocale (LC_ALL, "");
if ((locale = setlocale (LC_ALL, NULL)) == NULL)
return -1;
printf ("%s\n", locale);
return 0;
}
たとえば、私のシステムでは、これにより出力が得られます。es_ES.utf8
興味深い部分は、ドット「。」の後の部分です。これは文字エンコーディングを指定するためです (上記の例では utf8)。
古いバージョンには既定のロケールを設定するバグがあるようです。(参照: http://connect.microsoft.com/VisualStudio/feedback/details/709505/setlocale-lc-all-returns-incorrect-default-system-locale )