печать utf8 в glib - PullRequest
       8

печать utf8 в glib

6 голосов
/ 22 июня 2010

Почему символы utf8 не могут быть напечатаны с помощью функций glib?

Исходный код:

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

8 голосов
/ 22 июня 2010

Функции 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 (); языковой стандарт никогда не меняется эффект какой-то другой рутины.

1 голос
/ 23 июня 2010

Вам нужно инициализировать кодировку локали, вызвав setlocale при запуске вашей программы.

setlocale(LC_CTYPE, "")

Обычно это выполняется для вас, если вы используете какую-либо функцию инициализации, например gtk_init(..) или аналогичную.

1 голос
/ 22 июня 2010

Строка, передаваемая из g_print () в glibc, необязательно находится в кодировке UTF-8, поскольку g_print () выполняет преобразование набора символов в набор символов, указанный в локали.

0 голосов
/ 22 июня 2010

Обычно не рекомендуется использовать в текстовых файлах что-либо кроме 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.

Надеюсь, это поможет.

...