iconv_open() 함수는 dest, source 형식으로 인자를 받고
iconv() 함수는 2중 포인터를 사용한다.

#include <iconv.h>

iconv_t iconv_open(const char *tocode, const char *fromcode);
size_t iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);

iconv_open(TO, FROM);
이므로 반대로 넣으면 이상하게 나온다. 주의요망!

그리고 iconv() 함수는
문자열 변수들은 2중 포인터로 넘겨주고(왜?)
inbytesleft는 strlen(*inbuf) 의 값을
outbytesleft는 strlen(*outbuf) 의 값을 넣어주면된다.

물론 변환에 따라서, 길이가 가변적으로 달라질수 있기 때문에 주의해야 한다.

만약, 변환중 메모리가 넘치게 되면 EILSEQ 에러가 발생하게 되며, (물론 넘치기 전에 데이터는 빼낼수 있다.)
변수의 포인터가 2중 포인터가 아니면
"__gconv: Assertion `outbuf != ((void *)0) && *outbuf != ((void *)0)' failed."
이런 에러를 만나게 될 것이다.


#include "stdio.h"
#include "string.h"
#include "iconv.h"
#include "errno.h"

#define BUFF_SIZE 64

int main()
{
        iconv_t cd = iconv_open("UNICODE", "UTF-8");
        if (cd == (iconv_t)(-1))
        {
                perror("iconv_open");
                return 0;
        }

        char inBuf[BUFF_SIZE] = "Hello world";
        int inBufSize = sizeof(inBuf);

        char outBuf[BUFF_SIZE];
        int outBufSize = sizeof(outBuf);
        memset(outBuf, 0, outBufSize);

        // convert
        size_t readBytes = strlen(inBuf);
        size_t writeBytes = sizeof(outBuf);
        char* in = inBuf;
        char* out = outBuf;

        printf("readBytes:%d writeBytes:%d\n",readBytes,writeBytes);

        if (iconv(cd, &in, &readBytes, &out, &writeBytes) == -1)
        {
                printf("failed to iconv errno:%d EILSEQ:%d\n", errno, EILSEQ);
        }
        else
        {
                int idx;
                printf("in:%x out:%x\n",in,out);
                printf("readBytes:%d writeBytes:%d\n",readBytes,writeBytes);
                for(idx = 0; idx < BUFF_SIZE; idx++)
                {
                        printf("%03d %c %x\t\t", idx, inBuf[idx], inBuf[idx]);
                        printf("%03d %c %x\n", idx, outBuf[idx], outBuf[idx]);
                }
                outBuf[writeBytes] = '\0';
        }

        iconv_close(cd);
        return 0;
}


2010/04/20 - [Linux] - linux iconv 테스트
2010/04/19 - [Linux] - iconv

Posted by 구차니

댓글을 달아 주세요

  1. 제 블로그에 담아가겠습니다~ 좋은자료 감사드려요!

    2012.04.26 17:13 신고 [ ADDR : EDIT/ DEL : REPLY ]
  2. ㅁㄴㅇㅁㄴㅇ

    25번 라인 size_t readBytes = strlen(inBuf)+1; 이 되어야할 것같습니다

    2014.08.12 21:18 신고 [ ADDR : EDIT/ DEL : REPLY ]
    • +1은 대개 malloc 시 NULL 공간을 넣기 위함인데
      지금은 NULL을 처리할 이유가 없기 때문에 +1을 해줄 필요는 없을것으로 생각됩니다.

      2014.08.12 21:27 신고 [ ADDR : EDIT/ DEL ]
  3. ㅁㄴㅇㅁㄴㅇ

    아, 제가 malloc한 문자열에서 이 코드를 사용하다 부딪힌 문제였네요. 감사합니다 ㅎㅎ

    2014.08.12 21:32 신고 [ ADDR : EDIT/ DEL : REPLY ]