C 在glib中打印utf8
为什么utf8符号不能通过glib功能打印 源代码:C 在glib中打印utf8,c,glib,utf-8,C,Glib,Utf 8,为什么utf8符号不能通过glib功能打印 源代码: #include "glib.h" #include <stdio.h> int main() { g_print("марко\n"); fprintf(stdout, "марко\n"); } 您可以看到glib无法打印utf8,而fprintf可以: [marko@marko-work utf8test]$ ./main ????? марко 从g_print()传递到glibc的字符串不一定采用
#include "glib.h"
#include <stdio.h>
int main() {
g_print("марко\n");
fprintf(stdout, "марко\n");
}
您可以看到glib无法打印utf8,而fprintf可以:
[marko@marko-work utf8test]$ ./main
?????
марко
从g_print()传递到glibc的字符串不一定采用UTF-8编码,因为g_print()会将字符集转换为区域设置指定的字符集。fprint函数假定使用它们打印的每个字符串都正确编码,以匹配终端的当前编码。g_print()不假设并将转换编码(如果它认为有必要);当然,如果之前的编码是正确的,这是一个坏主意,因为这很可能会破坏编码。终端的区域设置是什么 您可以在大多数系统上通过环境变量设置正确的区域设置,也可以使用setlocale函数通过编程方式进行设置。语言环境名称取决于系统(不是POSIX标准的一部分),但在大多数系统上,以下功能都可以使用:
#include <locale.h>
:
setlocale(LC_ALL, "en_US.utf8");
#包括
:
setlocale(LC_ALL,“en_US.utf8”);
除了LC_ALL,您还只能为某些操作设置区域设置(例如,“en_US”将导致英文数字和日期格式,但您可能不希望数字/日期以这种方式进行格式设置)。要引用setlocale手册页中的内容:
LC_全部设置整个区域设置
一般来说
LC\u COLLATE为字符串设置区域设置
排序例程。这个控制
按字母顺序排列
strcoll()和strxfrm()
LC_CTYPE为
ctype(3)和多字节(3)函数。
这将控制对目标的识别
大写和小写,字母或非字母
人物等等
LC_消息为消息设置区域设置
目录,请参见catopen(3)功能
LC\U货币设置一个区域设置
格式化货币价值;这
影响localeconv()函数
LC\u数值设置的区域设置
格式化数字。这就控制了
中小数点的格式设置
函数中浮点数的输入和输出
例如printf()和scanf(),如
以及localeconv()返回的值
LC\U时间为设置区域设置
使用
strftime()函数
所有系统上始终可用的仅有两个区域设置值是“C”、“POSIX”和“”
默认情况下仅定义三个区域设置:空字符串“”(表示本机环境)
以及“C”和“POSIX”语言环境(表示C语言环境)。NULL的区域设置参数
使setlocale()返回当前区域设置。默认情况下,C程序在“C”语言环境中启动。这个
库中唯一设置区域设置的函数是setlocale();区域设置作为一个侧面永远不会改变
其他一些常规的影响
通常不建议在文本文件中使用ASCII以外的任何内容。您应该使用类似的工具来翻译来自不同语言的单词。如果这是不可能的,那么您应该将字符串存储在代码中的UTF-8中 请尝试打印此字符串(它是字符串的十六进制表示形式): 这在printf中适用(无法在此处使用glib进行测试):
#包括
char hex_marco[]={0xD0,0xBC,0xD0,0xB0,0xD1,0x80,0xD0,0xBA,0xD0,0xBE,0};
内部主(空)
{
printf(“%s\n”,十六进制);
返回0;
}
将输出重定向到文件,并将其视为UTF-8
希望有帮助。您需要在程序启动时调用setlocale来初始化区域设置的编码
setlocale(LC_CTYPE, "")
如果您使用一些初始化函数,如
gtk_init(..)
或类似函数,通常会执行此操作。在setlocale(LC_ALL,“en_US.UTF-8”)之后,一切都可以工作,但如果没有它,并且使用LANG=en_US.UTF-8./main,则无法工作。为什么会这样?系统默认值为en_US.UTF-8。您不需要导出变量以使子流程可见吗?此外,变量的名称如手册页上所示,请尝试导出LC_ALL=en_US.utf8&./main;也许只为字符串打印设置LC_CTYPE就足够了。若要“保存”变量,则需要导出。如果您只想将其用于一个应用程序,那么将其放在程序名之前就足够了。无论如何,我已经完成了LANG、LC_ALL和LC_CTYPE的导出。没有什么。还是不行。奇怪…使用setlocale(LC_CTYPE,”)
!!重要的是始终使用setlocale的“
字符串,而不是硬编码的区域设置。如果将其设置为“”,则它不一定是UTF8,并且可能再次无法正确打印,因为“”表示没有区域设置,并且没有区域设置意味着没有为字符串定义ASCII以外的任何内容。*.c文件中的“marko”就是一个例子。我没有在源代码中使用UTF-8。正确的答案已经给出了。无论如何谢谢你!我不太确定。我找不到你相信现代油嘴滑舌版本的证据。例如,对于Glib2.56.4和更早版本,这不起作用。
char hex_marco[]={0xD0, 0xBC, 0xD0, 0xB0, 0xD1, 0x80, 0xD0, 0xBA, 0xD0, 0xBE, 0};
#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;
}
setlocale(LC_CTYPE, "")