9

Why utf8 symbols cannot be printed via glib functions?

Source code:

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

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

Build it like this:

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

You could see that glib can't print utf8 and fprintf can:

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

4 回答 4

10

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) 和 multibyte(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();语言环境永远不会因为某些其他例程的副作用而改变。

于 2010-06-22T11:14:20.077 回答
2

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

setlocale(LC_CTYPE, "")

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

于 2010-06-23T00:36:25.193 回答
1

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

于 2010-06-22T11:10:44.967 回答
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。

希望能帮助到你。

于 2010-06-22T11:16:59.560 回答