'멀티바이트'에 해당되는 글 1건

  1. 2011.08.11 UNICODE와 MBCS 호환성 및 사용법
비공개2011. 8. 11. 09:47
현업에서 일하다보면 문자열을 다양하게 주물러야 할 때가 많다.
현재도, EXECL에 저장되어 있는 태국어를 내가 만든 툴에서 가져와 저장할 때 데이터가 깨지는 현상이 발생하였다.

뭐, Tool 자체적으로는 다른나라 신경안쓰고 만들었지만 앞으로 태국, 중국, 대만, 일본 등 다양한 나라에서도 이 Tool을
사용해야하는데 이참에 다국어를 어느정도(?) 지원하게끔 만들려고 한다.

가장 먼저 부딛히는 것이... 

1
2
CString     rtnStr = vt.bstrVal;   // Success! BSTR 타입.
std::string rtnStr = vt.bstrVal;   // Error!

이처럼 같은 문자열을 처리하도록 만든 클래스가 서로 다르게 동작한다. 진작 이점은 알고 있었고 주어들은것도 있지만
여지껏 기본동작만을 사용하기에 별문제가 없어 그냥 대충 암거나 사용했던것이 기억이 난다.

허나, 조금더 복잡하고 다양한 기능을 제공하기 위해서는 속도, 안정성, 유지보수 등이 도마위에 오르기 때문에 내가 지금 사용하고 있는 것들의 사용법 혹은 개념들을 정확히 알고 있어야 한다. 그렇지 않으면 매번 같은 문제로 골머리 썩는 좀비 프로그래머가 되는 것이다. 생각 또 생각을 달고 살아야하는게 프로그래머의 길! 이 아닐까 싶다. 치매는 안걸릴듯 ㅋㅋ


CString 과 std::string의 차이점은 뭔가? 

-  std::string은 말그대로 표준 템플릿 라이브러리이다. UNICODE 사용은 std::wstring 형태로 지원한다.
   사용을 위해서는 #include <iostream> 가 필요하다.

-  CString은 마이크로소프트에서 제작 및 배포하는 템플릿 라이브러리로 동일 이름으로 UNICODE를 지원한다.
    MFC 프로젝트를 생성하면 기본적으로 포함되어 사용이 가능하나 아니라면 atlstr.h 를 포함시켜줘야
    사용가능하다.

■ 유니코드(UNICODE)와 멀티바이트(MBCS)를 동시에 다루는 프로젝트 내에서의 대응?

- MBCS와 UNICODE 상호호환 되는 코드를 작성하자.
  여기서 말하는 호환은 문자열을 런타임단계에서 서로 인식하는것을 말하는 것이 아니라
  프로젝트 속성에서 UNICODE 와 MBCS 사용을 변경하여도 문제가 발생하지 않고 제대로 동작하는 것을 말한다.


먼저, 멀티바이트(MBCS) 와 유니코드(UNICODE)의 관계를 알아보자.
각각의 기본개념은 http://blog.daum.net/coolprogramming/87  를 참고하자!

        - MBCS와 UNICODE가 호환되게 코딩하는 방법

1) 모든 문자열 상수는 TEXT() 키워드로 감싸준다. ex) "나는 가수다" => TEXT("나는 가수다")
2) char => TCHAR
3) char* => LPTSTR
4) const char* => LPCTSTR

- MBCS 와 UNICODE console 출력 함수 or 매크로
 
MBCS     출력 : cout / printf
UNICODE 출력   : wcout / wprintf
MBCS / UNICODE 호환 매크로 : _tprintf
- 일반적으로 사용 코드

1) MBCS 
 
1
2
char* message = new char[20];
sprintf( message, "%s", "정의란 무엇인가?" );

2) UNICODE 
 
1
2
wchar_t* message = new wchar_t[20];
swprintf( message, L"%s", L"정의란 무엇인가?);

MBCS UNICODE 호환 코드

1
2
TCHAR* widestring = new TCHAR[20];
wsprintf( widestring, TEXT("%s"), TEXT("정의란 무엇인가?") );


std::cout은 UNICODE로 된 문자열 정보를 제대로 출력하지 못한다. wcout 사용
호환되는 cout 계열은 없나 ㅋㅋ

UNICODE  문자열을 출력하려고 wcout를 사용하다보면 아무것도 출력이 안될때가 있다.
 아래 코드를 추가해주자.
 
1
2
3
4
#include <locale>
	
//호출
setlocale( LC_ALL, "Korean" );  // Console 화면에 한국어 출력






< 프로젝트 문자 집합 설정에 따른 CString 과 std::string의 차이! >

 

CString과 std::string은 어느정도 상호 호환이 가능한가를 알아보고, 
더불어 UNICODEMBCS 일 때 각각 어떻게 인식하는지 테스트 해 보았다.
 
 
■ 사용 문자집합 : UNICODE

- CStringUNICODE 지원 )


1
2
3
4
5
6
7
CString = char*;				// compile success
CString = const char*;			// compile success
CString = CString + const char*; 	              // compile success
CString = CString + CString;		        // compile success
	
CString = CString + std::string;		// compile error
CString = std::string; 			                      // compile error

- std::string


1
2
3
4
5
6
7
8
std::string = char*;				// compile success
std::string = const char*;			// compile success
	
std::string = CString + const char*; 		      // compile error
std::string = std::string + const char*;  	      // compile error
std::string = CString + CString;		// compile error	
std::string = CString;   			                      // compile error	
std::string = CString + std::string;		// compile error


■ 사용 문자집합 : MBCS

- CString

1
2
3
4
5
6
7
CString = char*;				// compile success
CString = const char*;			// compile success
CString = CString + const char*; 		      // compile success
CString = CString + CString;			// compile success
	
CString = CString + std::string;		// compile error
CString = std::string; 				              // compile error

- std::string

1
2
3
4
5
6
7
8
std::string = char*;				// compile success
std::string = const char*;			// compile success
std::string = CString + const char*; 		      // compile success
std::string = std::string + const char*; 	              // compile success
std::string = CString + CString;		// compile success	
std::string = CString;   			                      // compile success
	
std::string = CString + std::string;		// compile error

결론 : MBCS 와 UNICODE 호환까지 생각한다면 CString 사용하자.
         그리고 일반적으로 개발자들은 CString을 std::string보다 사용하기 편리하다고 생각하고 있다고 한다.
Posted by 닭꽝