在glib中打印utf8

时间:2010-06-22 10:51:11

标签: c glib utf-8

为什么无法通过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)

你可以看到glib无法打印utf8和fprintf可以:

[marko@marko-work utf8test]$ ./main 
?????
марко

4 个答案:

答案 0 :(得分: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(),as                 以及localeconv()返回的值。

     

LC_TIME为其设置区域设置   使用。格式化日期和时间   strftime()函数。

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

  

默认情况下只定义了三个语言环境:空字符串“”(表示本机环境)   以及“C”和“POSIX”语言环境(表示C语言环境)。 locale参数为NULL   导致setlocale()返回当前的语言环境。默认情况下,C程序以“C”语言环境开始。该   只有在设置语言环境的库中的函数才是setlocale();区域设置永远不会改变   其他一些常规的效果。

答案 1 :(得分:1)

从g_print()传递给glibc的字符串不一定是UTF-8编码,因为g_print()会将字符集转换为语言环境指定的字符集。

答案 2 :(得分:1)

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

setlocale(LC_CTYPE, "")

如果您使用gtk_init(..)或类似的初始化函数,通常会执行此操作。

答案 3 :(得分:0)

通常建议在文本文件中使用除ASCII之外的任何内容。您应该使用gettext之类的工具来翻译不同语言的单词。如果这是不可能的,那么你应该在你的代码中将你的字符串存储在UTF-8中。

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

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

这对我在printf中起作用(不能用glib测试):

#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。

希望它有所帮助。