공부/WINAPI

인코딩 변환 함수(MultiByteToWideChar(), WideCharToMultiByte())

sudo 2021. 12. 10. 04:03
출처에 표시해놓은 블로그에서 유니코드<->멀티바이트 변환 함수를 잘 정리해놓아서 출처를 밝히고 여기 옮긴다.
MultiByteToWideChar()함수와 WideCharToMuliByte()함수를 사용해서 인코딩을 변환해 주는 것도 가능합니다. 이 두함수는 윈도우에서만 지원합니다. 따라서 OS 디펜던시가 없는 라이브러라 같은 것을 개발하신다면 이 두함수는 사용하실 수 없긴 하지만 많은 윈도우 개발자들이 사랑하는 함수죠. 
먼저 MBCS를 UTF-16으로 바꾸는 함수입니다.
int MultiByteToWideChar(
UINT CodePage, // 원본 스트링의 현재 인코딩 상태
DWORD dwFlags, // 0을 쓰면 된다.
LPCSTR lpMultiByteStr, // 변환하려는 문자열
int cbMultiByte, // -1을 넣으면 lpMultiByteStr의 길이를 알아서 계산
LPWSTR lpWideCharStr, // 변환된 유니코드를 저장할 공간
int cchWideChar // 유니코드를 저장할 공간의 사이즈
);

첫번째 인자에는 CP_ACP나 UTF-8둘중 하나를 넣으시면 됩니다. 
이함수는 특이한 기능이 있는데 맨마지막 인자에 0을 넣으면 필요한 wchar_t의 공간을 리턴합니다. 이를 이용해서 변환된 문자열에 딱맞는 공간을 할당 하실 수 있습니다. 다음은 반대로 UTF-16을 MBCS로 바꾸는 함수입니다.
 
int WideCharToMultiByte(
UINT CodePage, // 변환 타겟 인코딩
DWORD dwFlags, // 0
LPCWSTR lpWideCharStr, // 원본 스트링
int cchWideChar, // -1을 넣으면 원본 스트링 길이가 자동할당
LPSTR lpMultiByteStr, // 목적지
int cbMultiByte, // 목적지 사이즈
LPCSTR lpDefaultChar, // 실패시 사용
LPBOOL lpUsedDefaultChar // 실패 여부 판단
);
 
 
MultiByteToWideChar()함수와 거의 같은데 인자가 두개 더 있습니다. lpDefaultChar인자는 인코딩이 실패했을 때 실패한 문자열 대신 사용될 문자열입니다. 보통 NULL로 지정하시면 됩니다. 마지막 인자 lpUsedDefaultChar는 변환에 실패한 문자가 하나라도 있을 때 TRUE를 리턴합니다. 유니코드는 MBCS보다 사이즈가 큰 집합이기 떄문에 MBCS에서 유니코드로의 변환은 실패할 일이 없지만 반대는 실패할 수도 있음을 기억하셔야 합니다.
 
좀 신기한건 두 함수의 첫번째 인자가 하나는 원본 스트림의 인코딩 상태이고, 다른 하나는 변환 타겟 인코딩 상태인데, 아마 윈도우에서 유니코드 인코딩은 UTF-16으로 고정이라 필요 없는 것 아닌가 추측해본다. 참고로 ANSI는 System Local Code Page이며, 한글 Windows에선 ANSI = CP949가 된다.

참고로 Windows에서 Unicode 인코딩은 UTF-16을 사용한다. 그러니까 유니코드로 변환은 고정적으로 UTF-16으로 인코딩한다는 것으로 보면 된다. 한국어를 사용하는 윈도우에서는 멀티바이트일때 CP949를 디폴트로 사용한다. 따라서 WideCharToMultiByte 사용시 CodePage 인자로 UTF-8을 넣는게 아니라 CP_ACP를 넣으면 CP949로 인코딩된다.

 

인코딩 방식을 바꾸는게 아니라 유니코드->멀티바이트 변환시 아래와 같이 쓰면 된다

wchar_t strUnicode[256] = {0,};
char    strMultibyte[256] = {0,};
wcscpy_s(strUnicode,256,L"유니코드");
int len = WideCharToMultiByte( CP_ACP, 0, strUnicode, -1, NULL, 0, NULL, NULL );    
WideCharToMultiByte( CP_ACP, 0, strUnicode, -1, strMultibyte, len, NULL, NULL );

그게 아니라 유니코드->UTF-8 변환시 아래처럼 코드 페이지 인자를 UTF-8로 쓰면 된다

wchar_t strUni[256] =L"유니코드";
char strUtf8[256] ={0,};
int nLen = WideCharToMultiByte(CP_UTF8, 0, strUni, lstrlenW(strUni), NULL, 0, NULL, NULL);
WideCharToMultiByte (CP_UTF8, 0, strUni, lstrlenW(strUni), strUtf8, nLen, NULL, NULL);

 

 

Reference

https://hizstory.tistory.com/9

 

[MFC] 유니코드 멀티바이트 UTF-8 문자열 인코딩 변환 모음(퍼옴)

제목에서 밝힌 바와 같이 내용이 넘 좋아서 퍼왔습니다~ ^^ (http://yeobi27.tistory.com/280) 유니코드 -> 멀티바이트 1 2 3 4 5 wchar_t strUnicode[256] = {0,}; char    strMultibyte[256] = {0,}; wcscpy_s..

hizstory.tistory.com