본문 바로가기
프로그래밍/Windows API

MultiByteToWideChar와 WideCharToMultiByte 함수

by 호군 2010. 11. 9.
반응형
wcstombs()와 mbstowcs()를 이용해서 UNICODE <--> ANSI 문자열 변환을 할 때
문제가 발생 했다.
wcstombs()를 사용해서 WCHAR 문자열에서 char 문자열로 변환을 할 때
영어는 아무런 문제 없이 동작한다.
하지만 한글을 변환 할 때 문자열이 알수없는 문자들로 변환된다.
그 이유는 한글은 2byte이고 영문은 1byte라는데 있다.
WCHAR* uniStr은 _T("ab안녕") 이라는 문자열의 메모리 구조이다.

61

00

62

00

be

c8

b3

e7

0

0

char* ansStr은 위의 UNICODE문자열을 받기 위한 문자열 배열이다.
이 함수가 호출되었을 때  ansStr의 메모리를 보면 아래와 같다.

61

62

be

b3

0

이와 같은 구조로 들어가기 때문에 한글이 WCHAR 문자열이 char문자열로 변환이 되지 않는다.

이 문제를 해결하려면 아래의 함수를 사용 해야한다.
이 두 종류의 함수 중 어떤것이 낫다고 말은 못하겠다. 블러그들을 돌아다니다보면 WideCharToMultiByte와 MultiByteToWideChar들이 문제를 일이크는 경우가 있다고 한다.(모바일이던가?)
하지만 확실한건 윈도우 플렛폼에서 개발해야 한다면.. 한글을 써야 한다면... 아래 함수를 사용 해야 할 것이라고 본다.

[ ANSI 문자열 --> UNICODE 문자열 ] 
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWidCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar,
);

[ UNICODE 문자열 --> ANSI 문자열 ] 
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpMultiByteStr,
int cbMultiByte,
LPSTR lpWidCharStr,
int cchWideChar
);

lpMultiByteStr은 변환 되어질 문자열(ANSI)의 시작 주소
cbMultiByte는 변환 되어질 문자열(ANSI)의 바이트 크기(복사할 문자열 바이트)
lpWideCharStr은 변환된 문자열(UNICODE)을 수신 할 버퍼의 시작 주소
cchWideChar는 변환된 문자열(UNICODE)의 바이트 크기(복사된 문자열의 바이트 크기)
※ 한글이 들어가게되면 1byte가 아니라 2byte만큼의 크기를 바이트 크기에 반영해야된다.
   변환되어질 문자열의 바이트 크기만 잘 정한다면 변환된 문자열의 바이트 크기는 아무리
   크게 해도 넘어가지 않는 것같다.

//ANSI -> UNICODE
 char str[100] = "hello!!";
TCHAR* tstr = new TCHAR[strlen(str) + 1];
memset(tstr, '\0', sizeof(TCHAR) * ( strlen(str) + 1));

MultiByteToWideChar(CP_ACP, 0, str, strlen(str)+1, tstr1, strlen(str)+1);
 
//UNICODE -> ANSI
 TCHAR* tstr1 = _T("hello!!");
 char * str1 = new char [_tcslen(tstr1)*2 + 1];
 memset(str1, '\0', sizeof(char) * _tcslen(tstr1) + 1);
 
 WideCharToMultiByte(CP_ACP, 0, tstr1, _tcslen(tstr1)+1, str1, _tcslen(tstr1)*2 + 1 ,0 ,0);

반응형