vit*_*aut 35 c linux printf wchar non-ascii-characters
为什么下面的程序
#include <stdio.h>
#include <wchar.h>
int main() {
wprintf(L"??????, ???!");
}
Run Code Online (Sandbox Code Playgroud)
打印“女贞,先生!” 在 Linux 上?具体来说,为什么它将 Unicode 中的俄语文本音译为拉丁语,而不是将其转码为 UTF-8 或使用替换字符?
在 Godbolt 上演示此行为:https ://godbolt.org/z/36zEcG
非宽版会printf("??????, ???!")按预期打印此文本(“??????, ???!”)。
Sta*_*irl 31
因为宽字符的转换是根据当前设置的语言环境完成的。默认情况下,C 程序始终以仅支持 ASCII 字符的“C”语言环境开始。
您必须先切换到任何俄语或 UTF-8 语言环境:
setlocale(LC_ALL, "ru_RU.utf8"); // Russian Unicode
setlocale(LC_ALL, "en_US.utf8"); // English US Unicode
Run Code Online (Sandbox Code Playgroud)
或者到当前系统区域设置(这可能是您需要的):
setlocale(LC_ALL, "");
Run Code Online (Sandbox Code Playgroud)
完整的程序将是:
#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, "ru_RU.utf8");
wprintf(L"??????, ???!\n");
}
Run Code Online (Sandbox Code Playgroud)
至于您的代码在其他机器上按原样运行 - 这是由于 libc 在那里运行的方式。某些实现(如 musl)不支持非 Unicode 语言环境,因此可以无条件地将宽字符转换为 UTF-8 序列。