用printf打印出unicode字符

时间:2017-01-22 23:08:28

标签: c unicode printf

我试图通过将相应的十进制值传递给printf来打印出Ș。输出什么都没有。为什么我的代码不起作用?

#include <stdio.h>
int main()
{
    printf("%lc",536);
    return 0;
}

3 个答案:

答案 0 :(得分:4)

应用于l字段描述符的c长度说明符表示相应的参数类型为wint_t(在wchar.h中声明)。在您的代码中,参数的类型为int,它可能相同也可能不相同。如果确实不一样,那么行为是不确定的。您可以通过投射获得wint_t ...

    printf("%lc", (wint_t) 536);

这是表达wint_t常量的最安全,最便携的方式。

此外,这里有一个潜在的字符集问题。这是程序运行环境的问题,而不是程序本身。可以想象,您的程序确实以某种编码方式输出了有问题的字符,但是您运行的终端不知道如何处理它,或者可能只是没有字形。您应该能够通过将输出重定向到文件,然后检查文件的内容(可能是二进制文件)来测试它。

答案 1 :(得分:4)

在带有GCC 6.3.0的macOS Sierra 10.12.2上,如果我运行此程序(从mb37.c编译成mb37):

#include <locale.h>
#include <stdio.h>
#include <wchar.h>      /* wint_t */

int main(void)
{
    setlocale(LC_ALL, "");
    printf("%lc\n", (wint_t)536);
    return 0;
}

输出是:

$ ./mb37
Ș
$

我认为,这是理想的输出。如果删除setlocale()行,则根本不会产生任何输出 - 甚至不是换行符。使用的语言环境是en_US.UTF-8;我的终端也处理UTF-8。通过捕获并打印setlocale()的返回值 - 常规字符串来找到区域设置名称。

wint_t演员表是半可选的;事实上,没有强制转换的64位编译或<wchar.h>标题也会产生相同的输出,但wint_tint相同,这是一个轻微的巧合。这需要一些跟踪; wint_t定义为__darwin_wint_t,定义为__darwin_ct_rune_t,定义为int。为了便于携带,演员是必要的。在某些系统上,它可能没有必要(而macOS Sierra就是这样一个系统)。

printf()中的换行符不是100%必需的,但如果省略,则下一个提示会紧跟在U + 0218拉丁语大写字母S下方。最好确保输出以换行符结束。

答案 2 :(得分:0)

C中没有要求打印末尾没有换行符的行。试试&#34;%lc \ n&#34;。