我想以 UTF 8 打印字符,例如 ಚ (U+0C9A) 字符。我有以下应该可以工作的程序,但它要么打印出一个“?”或者什么都不做,具体取决于终端。我也尝试了 Windows 终端、命令提示符和 powershell。你能帮我吗?
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <wchar.h>
void utf8()
{
setlocale(LC_CTYPE, "en_US.UTF-8");
wchar_t ch = 0x0C9A;
wprintf(L"Character for U+0C9A: %lc\n", ch);
}
int main()
{
utf8();
return 0;
}
问题是,在 Windows 上,当您调用
printf
或 wprintf
等函数时,它们会将格式化字符串发送到称为 stdout
的缓冲区。默认情况下,此字符串使用 ANSI
编码发送到 stdout,该编码取决于系统的默认 code page
,它只能正确转换该代码页中存在的字符。您可以使用功能 _setmode(_fileno(stdout), _O_U8TEXT);
修改翻译模式(您可以在此处找到文档 Microsoft Learn)。
这是您程序的工作版本:
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <wchar.h>
#include <io.h>
#include <fcntl.h>
void utf8()
{
setlocale(LC_CTYPE, "en_US.UTF-8");
wchar_t ch = 0x0C9A;
wprintf(L"Character for U+0C9A: %lc\n", ch);
}
int main()
{
// set translation mode to Unicode mode
_setmode(_fileno(stdout), _O_U8TEXT);
utf8();
return 0;
}
但是,请注意,我自己在使用此解决方案时遇到了一个小问题,我在这个问题中对此进行了详细说明:表情符号问题。
第二种解决方案可能是将
SetConsoleOutputCP(CP_UTF8);
函数与窄打印函数一起使用(您可以在此处找到文档 Microsoft Learn)。
这是一个可行的解决方案:
#include <Windows.h>
#include <stdio.h>
#include <string.h>
#include <locale.h>
#include <wchar.h>
void utf8()
{
setlocale(LC_CTYPE, "en_US.UTF-8");
// pointer to a multibyte character aka a string of char
char* ch = "ಚ";
printf("Character for U+0C9A: %s\n", ch);
}
int main()
{
SetConsoleOutputCP(CP_UTF8);
utf8();
return 0;
}
请注意,第二个解决方案适用于 GCC,但不适用于 MSVC。