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