2015. 4. 23. 17:57ㆍIT-개발/winapi 및 MFC
제목에서 밝힌 바와 같이 내용이 넘 좋아서 퍼왔습니다~ ^^
(http://yeobi27.tistory.com/280)
유니코드 -> 멀티바이트
1 2 3 4 5 | 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 ); |
stl이용
1 2 3 4 | wstring strUni = L "유니코드" ; int len = WideCharToMultiByte( CP_ACP, 0, &strUni[0], -1, NULL, 0, NULL, NULL ); string strMulti(len,0); WideCharToMultiByte( CP_ACP, 0, &strUni[0], -1, &strMulti[0], len, NULL, NULL ); |
멀티바이트 -> 유니코드
1 2 3 4 5 | wchar_t strUnicode[256] = {0,}; char strMultibyte[256] = {0,}; strcpy_s(strMultibyte,256, "멀티바이트" ); int nLen = MultiByteToWideChar(CP_ACP, 0, strMultibyte, strlen (strMultibyte), NULL, NULL); MultiByteToWideChar(CP_ACP, 0, strMultibyte, strlen (strMultibyte), strUnicode, nLen); |
stl이용
1 2 3 4 | string strMulti = "멀티바이트" ; int nLen = MultiByteToWideChar(CP_ACP, 0, &strMulti[0], strMulti.size(), NULL, NULL); wstring strUni(nLen,0); MultiByteToWideChar(CP_ACP, 0, &strMulti[0], strMulti.size(), &strUni[0], nLen); |
유니코드 -> UTF-8
1 2 3 4 | 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); |
UTF-8 -> 유니코드로 변환
1 2 3 4 5 | wchar_t strUnicode[256] = {0,}; char strUTF8[256] = {0,}; strcpy_s(strUTF8,256, "utf-8글자.." ); // 이건 사실 멀티바이트지만 UTF8이라고 생각해주세요 -_-;; int nLen = MultiByteToWideChar(CP_UTF8, 0, strUTF8, strlen (strUTF8), NULL, NULL); MultiByteToWideChar(CP_UTF8, 0, strUTF8, strlen (strUTF8), strUnicode, nLen); |
기본적으로 UTF-8로 변형할땐 유니코드 상태에서만 변형을 시켜야 된다!.
만약 멀티 바이트를 UTF-8로 변형하고 싶을때에는 멀티바이트 -> 유니코드(UTF-16) -> UTF-8 UTF-8을 멀티바이트로 변형할때에는 UTF-8 -> 유니코드(UTF-16) -> 멀티바이트.. |
그런데 위와 같은 방식은.. 윈도우 환경에서만 사용한다면 너무 복잡하다...
우리 위대하신 MS에서 만들어주신게 있는데..
1 2 3 4 5 6 7 8 9 10 11 12 | #include <atlstr.h> // 요기에 정의.. 이거하면 MFC사용안하고도 CString를 사용할수 있다 void main() { wstring strUni = CA2W( "멀티바이트를 유니코드로 변환" ); string strMulti = CW2A(L "유니코드를 멀티바이트로 변환" ); string strUTF8 = CW2A(L "유니코드를 UTF8로변환" ,CP_UTF8); //string에서 포인터 얻어오는게 c_str()이듯. //CA2W나 CW2A에서 포인터 얻어오는건 m_psz 이다.. //그리고 CA2W CW2A는 기본적으로 CString 즉 (CAtlString)에 기반을 두고 고 있기때문에. //CString를 사용할때 가장 빠른다!!. // 만약 멀티 플레폼을 기준으로 한다면 CA2W는 사용 못함! } |
사용하기도 쉽고 속도면에서 MultiByteToWideChar,WideCharToMultiByte 보다 빠르다...
참고로 W는 wide , A는 ansi ,T는 TCHAR 이다.
펌 : http://icartsh.tistory.com/13
===================================================================================================================================================
Unicode 상에서 CString을 std:string을 바꾸기
or
펌 : http://chodalho.wordpress.com/2010/07/09/unicode-%EC%83%81%EC%97%90%EC%84%9C-cstring%EC%9D%84-stdstring%EC%9D%84-%EB%B0%94%EA%BE%B8%EA%B8%B0/
=====================================================================================================================================================
MultiByteToWideChar를 이용한 변환
MultiByteToWideChar()함수와 WideCharToMuliByte()함수를 사용해서 인코딩을 변환해 주는 것도 가능합니다. 이 두함수는 윈도우에서만 지원합니다. 따라서 OS 디펜던시가 없는 라이브러라 같은 것을 개발하신다면 이 두함수는 사용하실 수 없긴 하지만 많은 윈도우 개발자들이 사랑하는 함수죠.먼저 MBCS를 UTF-16으로 바꾸는 함수입니다.
첫번째 인자에는 CP_ACP나 UTF-8둘중 하나를 넣으시면 됩니다.
- CP_ACP : 시스템에서 사용하는 MBCS -> UTF-16
- UTF-8 : UTF-8 -> UTF16
- 기타 코드 페이지
MultiByteToWideChar()함수와 거의 같은데 인자가 두개더 있습니다. lpDefaultChar인자는 인코딩이 실패했을 때 실패한 문자열 대신 사용될 문자열입니다. 보통 NULL로 지정하시면 됩니다. 마지막 인자 lpUsedDefaultChar는 변환에 실패한 문자가 하나라도 있을 때 TRUE를 리턴합니다. 유니코드는 MBCS보다 사이즈가 큰 집합이기 떄문에 MBCS에서 유니코드로의 변환은 실패할 일이 없지만 반대는 실패할 수도 있음을 기억하셔야 합니다.
USE_CONVERSION 를 이용해 변환
이 매크로를 이용하면 아주 쉽게 문자열을 변환할 수 있습니다. 사용법은 아래와 같습니다.W2A말고도 여러 매크로를 제공하는데요. 아래와 같습니다. (const 변환용 매크로 제외)
매크로 | 설명 |
---|---|
A2W | LPCSTR -> LPWSTR |
W2A | LPCWSTR -> LPSTR |
A2T | LPCSTR -> LPTSTR |
T2A | LPCTSTR -> LPSTR |
T2OLE | LPCTSTR -> LPOLESTR |
OLE2T | LPCOLESTR -> LPCSTR |
이 매크로는 사용하기엔 편하지만 UTF8을 UTF-16 으로 변환하는데 쓰실 수 없습니다. 또 주의 해야 할 것이 있는데요. 각 매크로를 사용할 떄 변환에 필요한 공간이 스택에 할당된다는 점입니다. 따라서 실제적으로 아래를 주의 하셔야 합니다.
- 너무 큰 스트링을 변환하고 시도하면 스택 오버 플로가 날 수 있습니다.
- 루프 안에서 과도한 변환을 시도하면 스택 오버 플로가 날 수 있습니다.
- 스택에서 잡힌 공간이기 때문에 매크로의 결과를 리턴시키면 안됩니다.
CA2W계열의 클래스를 이용한 변환
USE_CONVERSION 를 이용한 변환이 편하긴 한데 위에서 말한대로 문제가 좀 있기 때문에 ATL 7.0이후 CATW계열의 클래스들이 새로 등장했습니다. 이 아이는 클래스인데다가 기본적으로 128바이트의 내부 버퍼를 가지고 있고(변경 가능 합니다만..), 이보다 크면 알아서 힙에 동적할당을 해주는 똑똑한 놈입니다.이런식으로 사용합니다. 주의할 점은 역시 위 코드에서 보이는 p를 리턴 시키면 안됩니다.(당연한 이야기지만) CA2W외 그밖의 클래스 들은 아래와 같습니다. (아래 목록은 cosnt와 버퍼 사이즈를 변경할 수 있는 EX가 붙어 있는 것들이 제외 되었습니다.)
클래스 | 설명 |
---|---|
CA2W | LPCSTR -> LPWSTR |
CW2A | LPCWSTR -> LPSTR |
CA2T | LPCSTR -> LPTSTR |
CT2A | LPCTSTR -> LPSTR |
CT2OLE | LPCTSTR -> LPOLESTR |
COLE2T | LPCOLESTR -> LPCSTR |
참조 : http://cafe.naver.com/newchany.cafe?iframe_url=/ArticleRead.nhn%3Farticleid=625
Tip : atlconv.h 를 인클루드 했는데도 CA2W 클래스를 찾을 수 없다는 컴파일 오류가 나온다면 atlconv.h 대신 atlbase.h 를 인클루드 하면 컴파일 오류를 해결할 수 있다.
추천 사용 방법
#include <string>
inline std::wstring _A2U( IN CONST CHAR *str ) { ATL::CA2W ca2w( str ); return std::wstring( ca2w ); }
inline std::string _U2A( IN CONST WCHAR *str ) { ATL::CW2A cw2a( str ); return std::string( cw2a ); }
#define U2A( str ) (CHAR *)_U2A( str ).c_str()
< 사용후기 >
- 아래 함수 이거 너무 편해서 좋은데, 웬만한 Loop 돌면 심심하면 STack OverFlow 발생하네요.
- 나중에 PG이 왜 죽는지도 모르는... Data 양에 따라서 PG에 Bug / Error 가 발생하는 찾기 힘든 Bug를 양산할 수 있음돠~ ㅠㅠ
USES_CONVERSION;
W2A();
A2W();
'IT-개발 > winapi 및 MFC' 카테고리의 다른 글
GetFileSizeEx 사용 - 큰일.개발.기억력상실~ㅠ (0) | 2015.06.04 |
---|---|
인증서 입히기~ 진짜 쓰는거만~ (0) | 2015.06.01 |
파일이름이 짧게 나올때~ㅠㅠ (0) | 2015.05.14 |
Dialog에선 않먹는 CCmdUI... (0) | 2014.08.06 |
... 이 이렇게 쉽게 표현 될줄이야~ ㅋ (0) | 2014.08.06 |