c - 在 cmd 中打印和存储西班牙语字符(á、é、í、ñ...)
问题描述
我将 Microsoft Windows 10 与 mingw-w64(gcc 版本 8.1.0,x86_64-posix-sjlj-rev0,由 MinGW-W64 项目构建)与cmd
. 当我尝试在 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在评论中所说,我尝试使用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
我怎么不完全理解这个功能我不知道为什么在最后一个例子中,控制台不显示重音存储字符,但在打印的字符中它会显示,而在上面的示例中发生了相反的情况。
解决方案
我玩了一段时间,唯一有效的是使用_setmode()
设置stdin
和stdout
接收宽字符,然后使用wchar_t
而不是char
存储文本。此代码在我的机器上按预期工作:
#include <stdio.h>
#include <fcntl.h>
#include <io.h>
int main(void) {
_setmode(_fileno(stdin), _O_WTEXT);
_setmode(_fileno(stdout), _O_WTEXT);
wchar_t c[20];
wprintf(L"pía\n");
wscanf(L"%ls", c);
wprintf(L"%ls", c);
}
已编辑:我更改了_setmode
from的参数,_O_U16TEXT
以避免因编译器的长度为 2 或 4 个字节_O_WTEXT
而导致的实现问题。wchar_t
推荐阅读
- sql - 我想获取 Windows 登录名而不是 SQL 登录名
- java - 将 restygwt 从 1.3 更新到 2.2.3 会破坏现有代码
- c++ - DirectX - 在不同线程之间共享资源句柄
- java - 在 arraylist 内投射时出错
- mongodb - InsertMany 在 mongodb 中不起作用
- reactjs - 使用 redux-forms,是否可以在两个表单(视图 1、视图 2)之间共享相同的状态?
- c# - 如何将原始二进制值恢复为字符串
- sql - AS400中的空字符串是否有类似于COALESCE的功能
- java - 在java中删除不必要的小数
- postgresql - 哪种方法更适合 PostgreSQL 中的 UPSERT?