2010-06-22 5 views
6

왜 glib 기능을 통해 utf8 기호를 인쇄 할 수 없습니까?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 함수를 사용하여 프로그래밍 방식으로 수행 할 수 있습니다. 것이다

#include <locale.h> 

: 

setlocale(LC_ALL, "en_US.utf8"); 

가 대신 LC_ALL 당신은 또한 특정 작업에 대한 로케일 (예 : "ko 페이지"를 설정할 수 있습니다 로케일 이름 시스템 (POSIX 표준의 일부)에 의존하지만, 대부분의 시스템에서 다음과 같은 작동합니다 영어 숫자 및 날짜 형식을 지정하지만 숫자/날짜 형식을 원하는 것은 아닙니다. 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"및 ""입니다.

단지 3 로케일은 기본적으로 정의되어있다 : "(네이티브 환경을 의미) 하고"빈 문자열 "C"와 "(C 언어 환경을 표시) POSIX"로케일. 로케일 인수가 NULL 이면 setlocale()은 현재 로케일을 리턴합니다. 기본적으로 C 프로그램은 "C"로켈에서 시작합니다. 로케일을 설정하는 라이브러리의 함수는 setlocale()입니다. 로케일은 측면으로 변경되지 않습니다. 다른 루틴의 효과.

+0

setlocale (LC_ALL, "en_US.UTF-8") 이후 모든 것이 작동하지만 LANG = en_US.UTF-8 ./main이 없으면 작동하지 않습니다. 왜 이런거야? 시스템 기본값은 en_US.UTF-8입니다. –

+0

하위 프로세스에서 볼 수 있도록 변수를 내 보내지 않아도됩니까? 또한 변수는 man 페이지에 표시된대로 이름이 지정되며'export LC_ALL = en_US.utf8 &&./main'; 문자열 인쇄를 위해서만 LC_CTYPE을 설정하는 것으로 충분할 수도 있습니다. – Mecki

+0

변수를 '저장'하려면 내보내기가 필요합니다. 하나의 응용 프로그램을 원한다면 프로그램 이름 앞에두기에 충분합니다. 어쨌든 LANG, LC_ALL 및 LC_CTYPE에 대한 내보내기를 완료했습니다. 아무것도. 아직도 작동하지 않습니다. 이상한 ... –

1

전달 된 문자열 g_print()에서 glibc로 반드시 UTF-8 인코딩으로되어있는 것은 아닙니다. 왜냐하면 g_print()가 문자 집합을 문자 집합으로 변환하기 때문입니다 로케일에 의해 ied.

0

일반적으로 이 아닌은 ASCII 이외의 텍스트 파일을 사용하는 것이 좋습니다. 다른 언어의 단어를 번역하려면 gettext과 같은 도구를 사용해야합니다. 이것이 문제가되지 않는다면 코드에 UTF-8로 문자열을 저장해야합니다. 이 printf와 나를 위해 작동

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; 
} 

는 출력을 리디렉션

이 하나를 (그것이 당신의 문자열의 16 진수 표현입니다) 인쇄 해보십시오 파일로 저장하고 UTF-8로 봅니다.

희망이 있습니다.

+0

* .c 파일의 "marko"는 예를 든 것입니다. 소스 코드에서 UTF-8을 사용하지 않습니다. 정답은 이미 주어졌다. 어쨌든 고마워! –

1

프로그램 시작시 setlocale을 호출하여 로캘의 인코딩을 초기화해야합니다. 당신이 gtk_init(..) 또는 이와 유사한 같은 일부 초기화 기능을 사용하는 경우

setlocale(LC_CTYPE, "") 

이것은 일반적으로 당신을 위해 수행됩니다.

관련 문제