char vs wchar_t
我正在尝试打印出一个wchar_t *字符串。 代码如下:
#include #include #include char *ascii_ = "中日友好"; //line-1 wchar_t *wchar_ = L"中日友好"; //line-2 int main() { printf("ascii_: %s\n", ascii_); //line-3 wprintf(L"wchar_: %s\n", wchar_); //line-4 return 0; } //Output ascii_: 中日友好
题:
-
显然我不应该将CJK字符分配给第1行中的char *指针,但我只是这样做了,第3行的输出是正确的,为什么呢? 第3行中的printf()怎么能给我非ascii字符? 它以某种方式知道编码吗?
-
我假设第2行和第4行的代码是正确的,但为什么我没有获得第4行的任何输出?
首先,在源代码中使用非ascii字符通常不是一个好主意。 可能发生的是汉字被编码为UTF-8,与ascii一起使用。
现在,至于为什么wprintf()
不起作用。 这与流方向有关。 每个流只能设置为普通或宽。 设置后,无法更改。 它是在第一次使用时设置的。 (由于printf
,这是ascii)。 之后,由于方向不正确, wprintf
将无法工作。
换句话说,一旦你使用printf()
你需要继续使用printf()
。 同样,如果从wprintf()
开始,则需要继续使用wprintf()
。
你不能混合printf()
和wprintf()
。 (在Windows上除外)
编辑:
回答关于为什么wprintf
线甚至wprintf
工作的问题。 这可能是因为正在编译代码,以便将中日友好
的UTF-8格式存储到wchar_
。 但是, wchar_t
需要4字节的unicode编码。 (Windows中的2个字节)
所以我可以想到两个选项:
- 不要打扰
wchar_t
,只需坚持使用多字节char
。 这是一种简单的方法,但如果用户的系统未设置为中文语言环境,则可能会中断。 - 使用
wchar_t
,但您需要使用unicode转义序列对中文字符进行编码。 这显然会使它在源代码中无法读取,但它可以在任何可以打印中文字符字体而不管语言环境的机器上工作。
第1行不是ascii,它是编译器在编译时使用的任何多字节编码。 在现代系统上,可能是UTF-8。 printf
不知道编码。 它只是向stdout发送字节,只要编码匹配,一切都很好。
您应该注意的一个问题是第3行和第4行一起调用未定义的行为。 您不能在同一个FILE
( stdout
)上混合基于字符和宽字符的io。 在第一次操作之后, FILE
具有“方向”(字节或宽),之后,任何执行相反方向操作的尝试都会产生UB。
你省略了一步,因此想错了路。
磁盘上有一个C文件,包含字节。 你有一个“ASCII”字符串和一个宽字符串。
ASCII字符串采用与第1行完全相同的字节并输出它们。 只要用户方的编码与程序员方的编码相同,这就有效。
宽字符串首先将给定的字节解码为unicode代码点并存储在程序中 – 这可能是您的错误。 在输出时,它们根据用户侧的编码再次编码。 这可以确保这些字符按照预期的方式发出,而不是在输入时发出。
您的编译器假定编码错误,或者您的输出终端设置错误。