试图在你的程序中修复错误的语言环境设置是错误的。您应该在您的环境中设置正确的语言环境并在您的代码中使用此值,例如:
setlocale(LC_ALL, "");
这是手册页所说的:
在主程序启动时,默认选择可移植的“C”语言环境。可以通过调用使程序可移植到所有语言环境:
setlocale(LC_ALL, "");
编辑:
看看你给我的最后一张截图,在阅读输入时似乎有些东西混淆了。
案例1:(没有任何调用的那个setlocale
)
……似乎不太有趣。与(默认)“C”语言环境一样,即使它似乎产生了正确的结果,它也只包含字符 U+00-U+7E,这或多或少是垃圾输入 - 垃圾输出的情况。值 0x9F 是编码 Unicode 字符 'LATIN SMALL LETTER C WITH CARON' (U+010D) 的代码页 825(参见:http : //de.wikipedia.org/wiki/Codepage_852)č
。
来回传递原始值,如果再次将相同的字节写入终端,则生成相同的输出也就不足为奇了。
案例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;
}
编辑:
区域设置检查
我忘了提到你的测试中最有趣的事情之一:unicode 字符 'LATIN SMALL LETTER Z WITH ACUTE' (U+017A) ź
(第二个屏幕截图中的一个输出)完全表示为值0x9f
(那是你在代码页 1250 中使用“原始”字符代码时得到报告。
不知何故,fgetws 似乎使用代码页 1250 而不是代码页 825 来解释字符代码。
对我来说,问题似乎仍然是语言环境设置以某种方式混淆了。可能您应该尝试运行以下代码并查看报告的语言环境。
#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)。
要检查的另一件事可能是您正在使用的 Visual Studio 的程序版本,因为在旧版本中设置默认区域设置似乎存在错误。(参见:http ://connect.microsoft.com/VisualStudio/feedback/details/709505/setlocale-lc-all-returns-incorrect-default-system-locale )