반응형
wcstombs()와 mbstowcs()를 이용해서 UNICODE <--> ANSI 문자열 변환을 할 때
문제가 발생 했다.
wcstombs()를 사용해서 WCHAR 문자열에서 char 문자열로 변환을 할 때
영어는 아무런 문제 없이 동작한다.
하지만 한글을 변환 할 때 문자열이 알수없는 문자들로 변환된다.
그 이유는 한글은 2byte이고 영문은 1byte라는데 있다.
WCHAR* uniStr은 _T("ab안녕") 이라는 문자열의 메모리 구조이다.
int WideCharToMultiByte(
UINT CodePage,
문제가 발생 했다.
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들이 문제를 일이크는 경우가 있다고 한다.(모바일이던가?)
하지만 확실한건 윈도우 플렛폼에서 개발해야 한다면.. 한글을 써야 한다면... 아래 함수를 사용 해야 할 것이라고 본다.
int WideCharToMultiByte(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpWidCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar,
LPCWSTR lpWidCharStr,
int cchWideChar,
LPSTR lpMultiByteStr,
int cbMultiByte,
LPCSTR lpDefaultChar,
LPBOOL lpUsedDefaultChar,
);
[ UNICODE 문자열 --> ANSI 문자열 ]
int MultiByteToWideChar(
UINT CodePage,
[ UNICODE 문자열 --> ANSI 문자열 ]
int MultiByteToWideChar(
UINT CodePage,
DWORD dwFlags,
LPCWSTR lpMultiByteStr,
int cbMultiByte,
LPSTR lpWidCharStr,
int cchWideChar
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);
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);
반응형
'프로그래밍 > Windows API' 카테고리의 다른 글
GetLastError() 함수로 얻는 애러코드 (0) | 2010.12.11 |
---|---|
동적 링크 라이브러리(DLL) 사용 / 만들기 #1 (0) | 2010.11.16 |
동적 링크 라이브러리(DLL) 사용 / 만들기 #2 (0) | 2010.11.12 |
INI 파일 제어 함수 (Get...Profile... / Write...Profile...) (0) | 2010.11.04 |
API 함수 레퍼런스 (0) | 2010.11.04 |
레지스터 관련 - RegSetValueEx 함수 (0) | 2010.10.27 |
레지스터 관련 - RegOpenKeyEx 함수 (0) | 2010.10.27 |
꼭 알아야 할 필수 API 함수 (0) | 2010.10.27 |
레지스터 관련 - RegCreateKeyEx 함수 (0) | 2010.10.27 |
Windows 와 Linux Thread Control 함수 비교 (동기화 함수) (0) | 2010.10.27 |