【发布时间】:2021-04-15 13:45:41
【问题描述】:
我正在使用带有 cmd 的带有 mingw-w64(gcc 版本 8.1.0,x86_64-posix-sjlj-rev0,由 MinGW-W64 项目构建)的 Microsoft Windows 10。当我尝试在 Windows 控制台上打印或存储然后打印西班牙语字符时,它显示错误。例如我试图执行这个程序:
#include <stdio.h>
int main(void) {
char c[20];
printf("pía\n");
scanf("%s", c);
printf("%s", c);
}
如果我引入一些西班牙语字符,返回的句子是可以的,但开头的打印显示错误:
pía
laíóñaú
laíóñaú
一些解决方案建议使用setlocale() 函数,但结果相同。其他解决方案是将 UTF-8 unicode 兼容性放在区域设置中:
但是现在错误是相反的,打印出来的还可以,但是当我引入一个奇怪的字符时,控制台没有显示它:
pía
lía
l
这有点令人沮丧,因为我看到的所有解决方案都是通过上述方法或通过设置setlocale() 解决的,但它们都不适合我,我不知道为什么。
编辑
正如 Mofi 在 cmets 中所说,我尝试使用 SetConsoleCP() 和 SetConsoleOutputCP() 更改控制台的代码页。在没有完全理解这些函数是如何工作的情况下,使用与上面相同的代码,我运行了几个结果错误的示例:
pía | p├¡a | p├¡a | pía
lía | lía | lía | lía
l | l | lía | la
input: 65001 output 65001 | input: 65001 output 850 | input: 850 output 850 | input: 850 output 65001
我怎么不完全理解这个功能我不知道为什么在最后一个例子中,控制台没有显示重音存储字符,但在打印的那个中它显示了,而在上面的例子中发生了相反的情况。
【问题讨论】:
-
我建议阅读 Microsoft 文档 Console Developer's Guide & API Reference 并在您的 C 编码应用程序中使用 Windows 控制台功能。 cmd.exe当前使用的code page根据为使用的账户配置的地区(国家)可以通过函数GetConsoleCP获取并通过SetConsoleCP设置。
-
GetConsoleCP和SetConsoleCP用于标准输入流。标准输出流的代码页可以用GetConsoleOutputCP 获取,用SetConsoleOutputCP 设置。两个流通常使用相同的代码页。我建议对西班牙语使用代码页 854 或 850。在 cmd 窗口中运行chcp时显示的计算机上帐户的默认代码页是哪个代码页? -
另请参阅 Microsoft 文档页面 Code Page Identifiers。我建议看Using another language (code page) in a batch file made for others 和eryksun 写的cmets。最好不要使用 UTF-8 以最大限度地兼容旧的 Windows 版本(如 Windows 7/XP),并使用包含 Windows 控制台应用程序应支持的所有西班牙字符的 OEM 代码页。
-
如果您只想通过文本编辑器使用代码页 Windows-1252 解决
pía的输出最有可能使用字节流70 ED 61 10 00(十六进制)编码的问题和 你的C编译器,我建议使用printf("\x70\xA1\x61\n"); /* That is pía OEM 850 encoded. */根据OEM code page 850编译带有字节流70 A1 61 10 00的字符串,独立于文本编辑器使用哪个代码页,几乎独立于哪个字符编码C编译器使用。 -
你必须先了解character encoding。另请参阅this page 上的介绍章节。您必须了解您输入的字符串如何与编辑器在 .c 源代码文件中的哪个字节流一起存储。接下来,您必须知道使用的 C 编译器在最终链接到可执行文件或库的目标文件中创建字符串的字节流时如何解释 .c 文件中的字符串字节。
标签: c windows winapi cmd windows-console