본문 바로가기

리눅스

iconv 함수 (인코딩 변환)

[1. 개요]

리눅스 C++ 코드 작성 시, 영어 외 문자열을 다루기 위해서 경우에 따라 인코딩 변환이 필요함.

  • 윈도우 OS 의 경우, 디폴트 인코딩이 EUC-KR
  • 리눅스 OS 의 경우, 디폴트 인코딩은 UTF-8
  • 가령 윈도우 에서 작성된 파일(한글로 작성된) 을 리눅스에서 읽어서 출력해야 하는 경우,,

또, 윈도우에서 컴파일 할 경우 기본적으로 문자열을 EUC-KR 로 처리하고,

리눅스에서 컴파일 할 경우는 문자열을 UTF-8 로 처리함.


[2. 상황]

리눅스 에서 아래 파일의 인코딩이 UTF-8 이 아닌 것을 확인.

  • euc.cpp: text/x-c; charset=iso-8859-1

이 파일의 작성된 한글 문자열은 출력 시 깨져서 나옴.

## 

반대로 아래와 같은 파일은 윈도우에서 컴파일 후 출력하면 한글 문자열이 깨져서 나옴.

  • utf.cpp: text/x-c; charset=utf-8

[3. 해결]

리눅스의 경우 iconv 함수를 이용하여, 문자열을 다른 charset 으로 인코딩 할 수 있다.

#include <iostream>
#include <iconv.h>
#include <string.h>

int main()
{
        char src[512] = "▒ȳ▒▒ϼ▒▒▒";
        std::cout << src << std::endl;

        // to charset, from charset
        iconv_t cd = iconv_open("UTF-8", "EUC-KR");
        if (cd == (iconv_t)(-1)) {
            perror("iconv_open failed");
            return -1;
        }

        char dest[512];
        char *inbuf = src;
        char *outbuf = dest;
        size_t inlen = strlen(src); // length of src
        size_t outlen = 512;        // buffer size

        std::cout << "before inlen: " << inlen << std::endl;

        // encoding...
        size_t result = iconv(cd, &inbuf, &inlen, &outbuf, &outlen);
        if (result == size_t(-1)) {
                std::cout << "iconv fail" << std::endl;
                iconv_close(cd);
                return -2;
        }

        std::cout << "outlen: " << outlen << std::endl;
        std::cout << "inlen: " << inlen << std::endl;
        std::cout << "result value: " << result << std::endl;
        std::cout << "result string: " << dest << std::endl;
        std::cout << "result string len: " << strlen(dest) << std::endl;
        std::cout << "offset0: " << (inbuf - src) << std::endl;
        std::cout << "offset1: " << (outbuf - dest) << std::endl;

        if (iconv_close(cd) == -1) {
                std::cout << "iconv_close fail" << std::endl;
                return -3;
        }

        return 0;
}
출력
▒ȳ▒▒ϼ▒▒▒
before inlen: 10
outlen: 497
inlen: 0
result value: 0
result string: 안녕하세요
result string len: 15
offset0: 10
offset1: 15
  • iconv_open() 시 charset 은 to, from 순서이다.
  •  
  • iconv() 호출 전...
  • inlen 에는 처리해야 할 바이트 수를 명시
  • outlen 에는 outbuf 의 남은 바이트 수를 명시
  •  
  • 인코딩 변환 종료 후 에는 iconv_close() 로 자원을 해제하도록 한다.\
  •  
  • euc-kr 문자열은 깨져서 나오지만, 해당 문자열의 인코딩 변환 후, 리눅스 shell 에서 정상 출력 됨.
  • 같은 의미의 문자열이지만, 인코딩 별 바이트 수가 다르다.

 

 

 

'리눅스' 카테고리의 다른 글

입출력 리다이렉션  (0) 2022.08.01
CentOS 7 Python3 & pip install  (0) 2021.10.26