7

我正在尝试打印出 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 行的任何输出?

4

3 回答 3

9

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

现在,至于为什么wprintf()不起作用。这与流方向有关。每个流只能设置为正常或宽。一旦设置,就无法更改。第一次使用时设置。(这是ASCII由于printf)。之后,wprintf由于方向不正确,它将无法工作。

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

你不能混用printf()wprintf()。(Windows 除外)

编辑:

回答为什么这wprintf条线不能单独工作的问题。这可能是因为正在编译代码,以便将 UTF-8 格式中日友好存储到wchar_. 但是,wchar_t需要 4 字节的 unicode 编码。(在 Windows 中为 2 字节)

所以我能想到两个选择:

  1. 不要打扰wchar_t,只需坚持使用 multi-byte chars。这是一种简单的方法,但如果用户的系统未设置为中文区域设置,则可能会中断。
  2. 使用wchar_t,但您需要使用 unicode 转义序列对中文字符进行编码。这显然会使它在源代码中不可读,但它可以在任何可以打印中文字体的机器上工作,而不管语言环境如何。
于 2011-09-21T07:42:08.747 回答
6

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

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

于 2011-09-21T07:44:28.283 回答
1

你忽略了一步,因此想错了方向。

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

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

宽字符串首先将给定的字节解码为 un​​icode 代码点并存储在程序中——也许这对您不利。在输出时,它们会根据用户端的编码再次编码。这可确保这些字符按预期发出,而不是按输入时发出。

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

于 2011-09-21T07:48:20.687 回答