2013-11-03 1 views
3

나는 iconv (3)를 사용하여 아래 코드를 사용하여 넓은 문자열을 UTF-8로 변환하려고합니다. 아래를 실행하면 출력 버퍼에 사용할 수있는 공간이 충분하지 않은 것처럼 iconv 호출이 E2BIG를 반환합니다. 이것은 (필자가 생각하기에) 출력 버퍼의 크기를 UTF-8에 대한 최악의 경우 확장을 인정하도록 만들었음에도 불구하고 발생합니다. 사실, 입력이 wchar_t로 끝나고 wchar_t 종결 자로 인코딩 된 간단한 ASCII 'A'이면 출력은 정확하게 '2 바이트/문자'여야합니다. 'A'다음에 '\ 0'이옵니다.iconv (3)를 사용하여 넓은 문자열을 UTF-8로 변환 하시겠습니까?

제 리눅스 시스템의 'man utf-8'은 UTF-8 바이트 시퀀스의 최대 길이가 6 바이트라고 말합니다. 그래서 나는 wchar_ts의 입력 버퍼 (널 터미네이터 뒤에 오는 문자) , 내 시스템에서 총 8 바이트 (sizeof (wchar_t) == 4 이후), 12 바이트 (2 * UTF8_SEQUENCE_MAXLEN)의 버퍼로 충분해야합니다.

실험에서 UTF8_SEQUENCE_MAXLEN을 16으로 늘리면 iconv의 반환 값은 성공을 나타냅니다 (15는 여전히 실패 함). 하지만 wchar_t 값이 UTF-8로 인코딩 할 때 너무 많은 바이트를 차지한다는 것을 알 수는 없습니다.

계산에 잘못 되었습니까? 16 바이트 UTF-8 시퀀스가 ​​가능합니까? 나는 무엇을 잘못 했는가?

#include <stdio.h> 
#include <stdlib.h> 
#include <iconv.h> 
#include <wchar.h> 

#define UTF8_SEQUENCE_MAXLEN 6 
/* #define UTF8_SEQUENCE_MAXLEN 16 */ 

int 
main(int argc, char **argv) 
{ 
    wchar_t *wcs = L"A"; 
    signed char utf8[(1 /* wcslen(wcs) */ + 1 /* L'\0' */) * UTF8_SEQUENCE_MAXLEN]; 
    char *iconv_in = (char *) wcs; 
    char *iconv_out = (char *) &utf8[0]; 
    size_t iconv_in_bytes = (wcslen(wcs) + 1 /* L'\0' */) * sizeof(wchar_t); 
    size_t iconv_out_bytes = sizeof(utf8); 
    size_t ret; 
    iconv_t cd; 

    cd = iconv_open("WCHAR_T", "UTF-8"); 
    if ((iconv_t) -1 == cd) { 
     perror("iconv_open"); 
     return EXIT_FAILURE; 
    } 

    ret = iconv(cd, &iconv_in, &iconv_in_bytes, &iconv_out, &iconv_out_bytes); 
    if ((size_t) -1 == ret) { 
     perror("iconv"); 
     return EXIT_FAILURE; 
    } 

    return EXIT_SUCCESS; 
} 

답변

5

iconv_open의 인수가 잘못되었습니다. 인자의 순서는 맨 페이지에 명확하게 명시된대로 (부터,까지), 아닌 (부터)까지입니다.

iconv_open("WCHAR_T", "UTF-8"); 

iconv_open("UTF-8", "WCHAR_T"); 

에 따라서 변화

는 예상대로 (다르게 변경) 코드는 상기 작동시킨다.

D 오. 맨 페이지를 더 자세히 읽어야합니다.

관련 문제