2010-06-22 34 views
6

为什么utf8符号不能通过glib函数打印?在glib中打印utf8

的源代码:

#include "glib.h" 
#include <stdio.h> 

int main() { 
    g_print("марко\n"); 
    fprintf(stdout, "марко\n"); 
} 

建立这样的:

gcc main.c -o main $(pkg-config glib-2.0 --cflags --libs) 

你可以看到,油腔滑调不能打印UTF8和fprintf可以:

[[email protected] utf8test]$ ./main 
????? 
марко 

回答

8

fprint函数假定您用它们打印的每个字符串都被正确编码以匹配终端的当前编码。 g_print()不会假设它并且会转换编码,如果它认为是必要的;当然这是一个坏主意,如果之前的编码实际上是正确的,因为这很可能会破坏编码。您的终端的区域设置是什么?

您可以在大多数系统上通过环境变量设置正确的语言环境,也可以使用setlocale函数以编程方式执行语言环境。语言环境的名称取决于系统(不是POSIX标准的一部分),但在大多数系统下面的工作:

#include <locale.h> 

: 

setlocale(LC_ALL, "en_US.utf8"); 

相反LC_ALL的你也可以只设置指定的工作区域(如“EN_US”将导致英文数字和日期格式,但也许你不希望数字/日期格式化)。要从setlocale手册页引用:

LC_ALL一般设置整个语言环境 。

LC_COLLATE设置字符串 排序规则的语言环境。这控制 strcoll()和strxfrm()的字母顺序。

LC_CTYPE设置 ctype(3)和多字节(3)函数的语言环境。 这控制了 字符的大写和小写,字母或非字母 等的识别。

LC_MESSAGES设置消息 目录的语言环境,请参阅catopen(3)函数。

LC_MONETARY设置格式化货币值的区域设置为 ;这个 影响localeconv()函数。

LC_NUMERIC为 格式化数字设置语言环境。这可控制 格式的 输入和输出函数 (如printf()和scanf())中的浮点数,如 以及localeconv()返回的值。

LC_TIME使用 strftime()函数为 格式化日期和时间设置语言环境。

在所有系统上始终可用的唯一两个区域设置值是“C”,“POSIX”和“”。

只有三个区域设置缺省定义:空字符串“”(其表示天然环境) 和“C”和“POSIX”地点(其表示C语言环境)。 NULL 的区域设置参数会导致setlocale()返回当前语言环境。默认情况下,C程序以“C”语言环境启动。 仅在设置语言环境的库中的函数是setlocale();语言环境永远不会改变为某个其他例程的效果。

+0

在setlocale(LC_ALL,“en_US.UTF-8”)之后一切正常,但没有它并且LANG = en_US.UTF-8 ./main,它不起作用。为什么是这样? 系统默认值是en_US.UTF-8。 – 2010-06-22 11:29:40

+0

您是否必须将变量导出到子流程才可见?此外,变量的名称如手册页所示,请尝试'export LC_ALL = en_US.utf8 &&。/ main';也许仅为字符串打印设置LC_CTYPE就足够了。 – Mecki 2010-06-22 12:08:34

+0

如果您想'保存'变量,则需要导出。如果您只想为一个应用程序使用它,则只需将其放在程序名称之前即可。无论如何,我已经完成了LANG,LC_ALL和LC_CTYPE的导出。没有。仍然不工作。奇怪... – 2010-06-22 13:25:35

1

传递的字符串从g_print()到glibc不一定采用UTF-8编码,因为g_print()将字符集转换为字符集指定由地区设置。

0

通常它是而不是建议在文本文件中使用除ASCII以外的任何内容。您应该使用像gettext这样的工具来翻译来自不同语言的单词。如果这没有问题,那么你应该在你的代码中以UTF-8格式存储你的字符串。

尝试打印这一项(这是你的字符串的十六进制表示):

char hex_marco[]={0xD0, 0xBC, 0xD0, 0xB0, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xBE, 0}; 

这在printf的工作,我(不能与油嘴测试这里):

#include <stdio.h> 

char hex_marco[]={0xD0, 0xBC, 0xD0, 0xB0, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xBE, 0}; 

int main(void) 
{ 
    printf("%s\n",hex_marco); 
    return 0; 
} 

输出重定向到文件并将其视为UTF-8。

希望它有帮助。

+0

* .c文件中的“marko”仅仅是一个例子。我没有在源代码中使用UTF-8。已经给出了正确的答案。不管怎样,谢谢你! – 2010-06-22 11:33:33

1

您需要在程序启动时通过调用setlocale来初始化语言环境的编码。

setlocale(LC_CTYPE, "") 

这通常是进行你,如果你使用像gtk_init(..)或类似的一些初始化函数。