unicode 와 ansi 를 섞어 쓰면서 std::string 과 std::wstring, CString 을 상호 변환하는 방법을 살펴 보자. unicode 를 쓰면서 MFC에서 STL 을 쓰기 위해선 이들을 서로 변경해야 할 경우가 많아 이 곳에 정리해 둔다.
환경 : Visual Studio 2010 on Windows 7 Professional SP1, English, 64-bit.
우선 기본적으로 MFC에서 unicode 과 ansi 를 상호변환하기 위해서는 CF2CT 형식을 따르며, 이 때 F 와 T 는 A와 T 중 하나의 값이 될 수 있다. T는 _T macro 에서 알 수 있듯이 multibyte 로의 변환을 의미하는 것이고, A 는 ANSI 를 의미한다. 따라서 ansi 에서 unicode 로 변경하기 위해선 CA2CT 를, unicode 에서 ansi로 변경하기 위해선 CT2CA 를 쓰면 된다. 또한 std::string은 class 이므로 CString 에서 std::string 을 만들 때는 std::string 의 생성자를 사용하면 된다. std::string --> CString 도 마찬가지.
MFC로 project 를 만들 때 UNICODE 를 사용하게 되면 CString 은 CStringT 로 기본적으로 코드 상의 모든 CString 이 unicode 로 지정된다(물론 _UNICODE macro 에 의해). 이 경우 모든 literal 문자열은 _T macro로 지정해 주어야 한다, 다음처럼.
_stimuliWnd.CreateEx(0,strClass,_T("stimuliWnd"),WS_POPUPWINDOW,0,0,width,height,NULL,NULL);
std::string 은 ansi version 이고 st::wstring 은 wide-string, 즉 unicode version 이다. 또한,
std::string::c_str() 함수는 std::string 의 객체를 const char* 로 접근할 수 있게 해주며,
CString::operator LPCTSTR() 은 CString 객체를 const char* 로 접근할 수 있게 해준다.
위의 ansi version 함수는 std::string 을 std::wstring 으로, CString::operator LPCTSTR() 을 CString::operator LPCWSTR() 으로 unicode version 으로 사용할 수 있다.
이제 기본적인 것들을 알았으니 CString <--> std::string 등의 변경 방법을 살펴 보자.
CString cstring(_T("CString::CStringT")); std::string str("std::string"); std::wstring wstr(_T("std::wstring")); // std::string <-- CString str = std::string(CT2CA(cstring.operator LPCWSTR())); // std::wstring <-- CString wstr = std::wstring(cstring.operator LPCWSTR()); // CString <-- std::string cstring = CString::CStringT(CA2CT(str.c_str())); // CString <-- std::wstring cstring = CString::CStringT(wstr.c_str()); // std::string <-- std::wstring str = std::string(CT2CA(wstr.c_str())); // std::wstring <-- std::string wstr = std::wstring(CA2CT(str.c_str()));
어렵지 않다.
CA2CT 는 ansi version const char* 를 multi-byte const char* 로 변경해 주는 것이고,
CT2CA 는 unicode version const char* 를 ansi version const char* 로 변경해 주는 것이고,
std::string 은 ansi version, std::wstring 은 unicode version 이고,
CString 은 _UNICODE 가 설정되어 있으면 CStringT 의 unicode version 으로 자동으로 바뀌며,
std::string 과 CString 은 모두 const char* 로 접근할 수 있게 해 주는 함수를 제공한다는 점,
을 생각하면 된다. 그러면 다음과 같이 자유자재로 왔다갔다 할 수 있다.
CString path; // [path] 설정. std::vector<std::wstring> files; GetFileNameList(std::wstring(path.operator LPCWSTR()), _T("*.txt"), &files, NULL, NULL); std::vector<std::wstring>::const_iterator pos; for(pos = files.begin(); pos != files.end(); pos++){ std::string file_name(CT2CA((path + _T("\\") + CString::CStringT(pos->c_str())).operator LPCWSTR())); // ~~ 작업. }
위에서 [path]는 CString 이므로 literal 문자 \ 는 _T("\\") 로 unicode 로 변경 후 더할 수 있다. 그 후, std::wstring 인 [pos]를 CString 으로 변경해서 덧붙인다. 그렇게 만들어진
path + _T("\\") + CString::CStringT(pos->c_str())
위 변수는 CString 타입의 객체이다. 따라서 이것을 다시 std::string 으로 만들기 위해 CT2CA 와 operator LPCWSTR 을 사용한 것이다.
참조 http://adnoctum.tistory.com/749