char vs wchar_t

时间:2011-09-21 07:38:24

标签: c encoding wchar-t

我正在尝试打印出一个wchar_t *字符串。 代码如下:

#include <stdio.h>
#include <string.h>
#include <wchar.h>

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_: 中日友好

问题:

  1. 显然我不应该将CJK字符分配给第1行中的char *指针,但我只是这样做了,第3行的输出是正确的,为什么呢?第3行中的printf()怎么能给我非ascii字符?它以某种方式知道编码吗?

  2. 我假设第2行和第4行的代码是正确的,但为什么我没有获得第4行的任何输出?

3 个答案:

答案 0 :(得分:8)

首先,在源代码中使用非ascii字符通常不是一个好主意。可能发生的是中文字符编码为UTF-8,与ascii一起使用。

现在,为什么wprintf()无效。这与流方向有关。每个流只能设置为普通或宽。设置后,无法更改。它是在第一次使用时设置的。 (由printf引起的ascii)。之后,由于方向不正确,wprintf将无效。

换句话说,一旦您使用printf(),您需要继续使用printf()。同样,如果您从wprintf()开始,则需要继续使用wprintf()

您无法混合printf()wprintf()。 (在Windows上除外)

编辑:

回答有关为什么wprintf行甚至不能自行运行的问题。这可能是因为正在编译代码,因此中日友好的UTF-8格式存储在wchar_中。但是,wchar_t需要4字节的unicode编码。 (Windows中的2个字节)

所以我可以想到两个选项:

  1. 不要打扰wchar_t,只需坚持使用多字节char。这是一种简单的方法,但如果用户的系统未设置为中文语言环境,则可能会中断。
  2. 使用wchar_t,但您需要使用unicode转义序列对中文字符进行编码。这显然会使它在源代码中无法读取,但它可以在任何可以打印中文字符字体的机器上工作,无论语言环境如何。

答案 1 :(得分:6)

第1行不是ascii,它是编译器在编译时使用的任何多字节编码。在现代系统上,可能是UTF-8。 printf不知道编码。它只是向stdout发送字节,只要编码匹配,一切都很好。

您应该注意的一个问题是第3行和第4行一起调用未定义的行为。您不能在同一FILEstdout)上混用基于字符和宽字符的io。在第一次操作之后,FILE具有“方向”(字节或宽),之后任何执行相反方向操作的尝试都会产生UB。

答案 2 :(得分:1)

你省略了一步,因此想错了方法。

磁盘上有一个C文件,包含字节。你有一个“ASCII”字符串和一个宽字符串。

ASCII字符串采用与第1行完全相同的字节并输出它们。 只要用户方的编码与程序员方的编码相同,这就可以工作。

宽字符串首先将给定的字节解码为unicode代码点并存储在程序中 - 这可能是你的错误。在输出时,它们根据用户侧的编码再次编码。这可以确保这些字符按照预期的方式发出,而不是输入它们。

您的编译器假定编码错误,或输出终端设置错误。