c-为什么wprintf在Linux上将Unicode中的俄语文本音译为拉丁语



为什么下面的程序是

#include <stdio.h>
#include <wchar.h>
int main() {
wprintf(L"Привет, мир!");
}

打印";女贞子,米尔"在Linux上?具体来说,为什么它将Unicode中的俄语文本音译为拉丁语,而不是将其转码为UTF-8或使用替换字符?

Godbolt上这种行为的演示:https://godbolt.org/z/36zEcG

非宽版printf("Привет, мир!")按预期打印该文本("Привер,мир!"(。

因为宽字符的转换是根据当前设置的区域设置完成的。默认情况下,C程序总是以"0"开头;C";仅支持ASCII字符的区域设置。

您必须先切换到任何俄语或UTF-8语言环境:

setlocale(LC_ALL, "ru_RU.utf8"); // Russian Unicode
setlocale(LC_ALL, "en_US.utf8"); // English US Unicode

或者到当前的系统区域设置(这可能是您所需要的(:

setlocale(LC_ALL, "");

完整的程序将是:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>
int main() {
setlocale(LC_ALL, "ru_RU.utf8");
wprintf(L"Привет, мир!n");
}

至于您的代码在其他机器上的工作方式,这是由于libc在那里的操作方式。有些实现(如musl(不支持非Unicode区域设置,因此可以无条件地将宽字符转换为UTF-8序列。

为什么它将Unicode中的俄语文本音译为拉丁语,而不是将其转码为UTF-8或使用替换字符?

因为程序的起始语言环境是默认语言环境,即C语言环境。因此,它正在将宽字符串转换为C语言环境。C语言环境既不处理UTF-8也不处理任何unicode,所以您的标准库最好将宽字符转换为C语言环境中使用的一些基本字符集。

您可以将区域设置更改为任何UTF-8区域设置,并且程序应该输出UTF-8字符串。

注意:(据我所知,在实现中(FILE流的编码是确定的,并且在选择流方向(宽与正常(时保存。在使用stdout执行任何操作之前,请记住设置区域设置(即this与this(。

相关内容

  • 没有找到相关文章

最新更新