gpt4 book ai didi

c++ - 为什么在使用 "C"语言环境时 printf 可以显示非 ASCII 字符?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:25:17 25 4
gpt4 key购买 nike

注意:我问的是 Microsoft Visual C++ 2008 上的实现定义行为(在 2005+ 上可能相同)。操作系统:Win7简体中文安装。

当我使用 printf 执行非 ASCII I/O 时,我感到很惊讶。例如

   // This won't be necessary as it's the system default code page.
//system("chcp 936");

// NULL to show current locale, which is "C"
printf ("%s\n", setlocale(LC_ALL, NULL));
printf ("中\n");
printf ("%s\n", setlocale(LC_ALL, "English"));
printf ("中\n");

输出:

Active code page: 936
C

English_United States.1252
?D

调试器中的内存占用显示"中"被编码为两个字节:0xD60xD0,这是代码点代码页 936 中的那个字符,用于简体中文。它不应该在 "C"locale 的代码点范围内,most likely , 是 0x0 ~ 0x7F

问题:

为什么在“C”语言环境下仍能正确显示字符?所以我猜测语言环境与 printf 没有关系?但是,我想问一下,为什么换成"English" locale 就不能显示了,这也和936不一样?有趣吗?

编辑:

我将标准输出重定向到一个文件并进行了一些测试。它表明无论设置何种语言环境,文件中都会保存正确的字符 "中"。它表明 setlocale() 连接到控制台显示字符的方式,这与我对其工作原理的理解相矛盾:printf 将字节/代码点放入输入缓冲区控制台,它使用自己的代码页(chcp 返回的内容)解释这些字节。

最佳答案

936 是相当棘手的代码页,它允许 2 个符号字符(类似于 UTF-8 完成的)。例如西里尔字母 (866) - 不允许使用双字节字符,其行为与“英语”相同。

因此,当您使用默认 (936) 代码页时,它知道如何处理 2 符号字符,而“英语”仅处理 0x0 ~ 0x7f

我也来回答为什么 wprintf(L"中") 失败。控制台应用程序和 Windows 窗口应用程序之间有很大的区别,它们使用不同的代码页以下是控制台和窗口之间的匹配:

DOS   |   Windows
------+----------
850 | 1252
936 | 54936
866 | 1251

因此,如果您想在控制台中看到正确的符号,请首先使用 WideCharToMultiByte - 它提供预期的转换以允许控制台在 936 中工作

关于c++ - 为什么在使用 "C"语言环境时 printf 可以显示非 ASCII 字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16383069/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com