본문 바로가기
컴퓨터/MFC_API

unicode 와 ansi, std::string 과 CString 상호 변경하기

by adnoctum 2013. 1. 7.




   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 형식을 따르며, 이 때 FT 는 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 을 사용한 것이다.