为什么wprintf将Unicode连字分成两个不同的字形?

码:

#include  #include  #define USE_W int main() { #ifdef USE_W const wchar_t *ae_utf16 = L"\x00E6 & ASCII text ae\n"; wprintf(ae_utf16); #else const char *ae_utf8 = "\xC3\xA6 & ASCII text ae\n"; printf(ae_utf8); #endif return 0; } 

输出:

ae和ASCII文本ae

而printf产生正确的UTF-8输出:

æ&ASCII文本ae

你可以在这里测试一下 。

printf只是将原始字节发送到您的终端; 它对编码一无所知。 如果您的终端配置为将其解释为UTF-8,它将显示正确的字符。

另一方面, wprintf确实知道编码。 它的行为就像它使用函数wcrtomb一样 ,它根据当前的语言环境将宽字符( wchar_t )编码为多字节序列。 如果默认语言环境恰好是"C" ,这是非常简约的,则字符æ会转换为“或多或少等效”的字节序列ae

如果使用UTF-8将语言环境明确设置为某些内容,例如"en_US.UTF-8" ,则输出符合预期 。 当然,每个系统支持的语言环境集都不同,因此对其进行硬编码并不好。