【发布时间】:2014-07-06 18:59:44
【问题描述】:
对于一个小项目,我需要在 Windows 的 CMD 中输出可能已本地化的文本字符串,并且从程序的参数中读取一些字符串。为了简化问题,我将使用一个简单的 echo 程序作为演示。
请考虑C语言中的sn-p:
#include <stdio.h>
int main(int argc, char **argv) {
// Display the first argument through the standard output:
if (argc > 1)
puts(argv[1]);
return 0;
}
这些是两次执行的输出:
$ test.exe Wilhelm
$ Wilhelm
$ test.exe Röntgen
$ R÷ntgen
您已经可以看到像ö 这样超出ASCII 的内容将无法正确显示。但它们在程序中被正确识别,例如,如果您执行以下操作:
if (argv[1][1] == 'ö')
puts("It is.");
将显示句子,因此程序正确接收字符。
所以我,好吧,可能需要 wchar_t 的东西,所以进行适当的更改并定义 UNICODE 和 _UNICODE 你会得到:
#include <stdio.h>
int wmain(int argc, wchar_t **argv) {
// Display the first argument through the standard output:
if (argc > 1)
_putws(argv[1]);
return 0;
}
这个测试程序的输出仍然是一样的。
环顾四周并阅读文档,我发现了一种解决方法,例如将语言环境设置为英语:文本将正确显示。修改第一个版本(没有wchar_ts)我最终得到了这个:
#include <stdio.h>
#include <locale.h>
int main(int argc, char **argv) {
// Get the previous locale and change to English:
char *old_locale = setlocale(LC_ALL, NULL);
setlocale(LC_ALL, "English");
// Display the first argument through the standard output:
if (argc > 1)
puts(argv[1]);
// Restore locale:
setlocale(LC_ALL, old_locale);
return 0;
}
("en-US" 似乎在 MinGW-w64 中不起作用,而 "English" 与它和 Microsoft Visual C++ 一起使用)
现在程序可以打印了,这样字符就可以在命令行窗口中正确显示了。
问题在于,在西班牙语系统或日语系统中,将内容设置为英语并不是最好的做法。所以我考虑以某种方式从系统中获取语言环境。我找到了一个名为_get_current_locale 的函数,它返回一个_locale_t,但它似乎根本不是我想要的:
_locale_t_variable->locinfo->lc_category[LC_ALL].locale(这是一个char *)似乎是NULL。
所以问题是,如何在命令行的语言环境中获取或显示文本?在 Windows 的 CMD(不一定是 Unicode)中处理本地化文本的正确方法是什么?
【问题讨论】:
-
你的问题有道理。
echo程序可以在我的 Win7 机器上正确回显Röntgen;所以你想要做的显然是可能的。 -
但是,
echo在 MS cmd shell 内部。它可以由外壳进行“特殊”处理...... -
默认情况下,命令提示符使用 OEM 代码页。设置 C 语言环境无关紧要。但是,您可以更改此代码页。
-
SetConsoleCP() 和/或 SetConsoleOutputCP() 与 CP_UTF8 或 65001 不会使程序输出字符,因为它们在程序的参数中输入。我当前的代码页是 437(不是 Unicode)并且可以输入/输出这些字符,我将在问题中添加该信息。
标签: c windows unicode cmd locale