본문 바로가기

3.구현/VC++

문자열 - 유니코드 팁 tstring

유니코드 팁

다음은 유니코드 문자열 처리에 있어서 기본적인 팁들을 모아두었다.

Generic Text Mapping

프로그램이 유니코드에 대응하기 위해서는 모든 single byte char 관련 타입들을 generic macro를 사용하도록 수정해야 한다.
(JS) 참 말이 이해하기 힘들다. 일반적인 문자(ascii)는 1바이트다. 한국어는 1바이트로 안된다. 이를 처리하기 위한 방식은 여러가지가 있고 그중에 하나가 Microsoft의 Unicode이다. 이는 윈도우즈 환경에서는 거의 표준이다. 사실 윈도우즈가 MS꺼니깐.
프로그램이 구동되는 환경은 상당히 다양하고, 또한 언어도 매우 다양하다. 영어권이라면 1바이트 문자열로 충분히 가능하지만 그외는 그렇지 않다. 모든 언어권을 지원할 수 있는 프로그램 개발이 필요하게 된다.
그래서 나온것이 매크로를 이용해서 특정 조건에서는 1바이트 문자열로 또다른 조건에서는 Unicode 문자열로 처리하게 된다.
이를 위해서 문자열 값을 나타내는 이중 따옴표(")와 같이 매크로를 사용하게 된다. 그 것이 아래 내용이다.

  • 모든 스트링 리터럴에는 _T 또는 _TEXT 를 붙일 것. 그러나, 특별히 wide string 을 사용할 경우 L"abc" 처럼 L 을 붙일 것
  • 모든 문자 배열에 대해서는 TCHAR 를 사용할 것. 그러나, 특별히 wide char 를 사용할 경우 wchar_t 를 사용할 것.
  • 모든 스트링 포인터에 대해서 LPCTSTR 혹은 LPTSTR 을 붙일 것
  • 스트링 관련 C 함수들에 대한 T 시리즈들을 사용할 것.

예)

아래 두개 사용법은 같은 결과을 갖습니다.

TCHAR *str1 = _T("This is test.");
TCHAR *str2 = _TEXT("This is test.");
// 이는 wide char로 Unicode로 만 사용
TCHAR *str3 = L"This is test";

그리고 문자열 처리 함수들 중에서 TCHAR 문자열을 처리하는 함수들이 있다. 이는 MSDN 문서를 보다보면 흔하게 나온다.
예를 들어 "strcpy function"를 보면 Generic-Text Routine Mapping이라는 항목에

TCHAR.H routing
_UNICODE & _MBCSnot defined
_MBCS defined
_UNICODE defined

으로 구분되는 것을 볼 수 있다.
여기에서 "TCHAR.H routine"에 있는 함수인 _tcscpy를 사용하라는 말이다.

XML 과 유니코드

유니코드로 인코딩된 XML 에 한글 엘리먼트 이름을 사용한 경우, 중문 혹은 영문 OS 에서 XPath 검색이 안되는 경우가 있다. 이는 프로그램 자체가 Non Unicode 이기 때문이며, 프로그램 자체를 유니코드로 만들면 문제가 없다.

그러나, 그것이 힘들 경우, Windows XP 이상부터 설정 가능한 Non Unicode Program 의 디폴트 언어를 한글로 지정하면 된다. 단 98 과 같은 오래된 언어에서는 이것이 안되는데, 이를 위해서는 프로그램 코드 자체에 유니코드로 XPath 스트링을 지정하면 된다.

pNode = pXMLDom->selectNodes( L"//캐릭터정보/*" );

STL 과 유니코드

STL 는 cpp에서 사용하는 표준 라이브러리이다. STL은 OS independent 이어야 하므로 MS VisualC++ 전용 매크로인 UNICODE 에 대응되는 어떤 정책도 가지고 있지 않다. 한마디로 TCHAR를 지원하지 않는다.
따라서, 개발자가 아래와 같이 자체적으로 문자열에서 TCHAR를 타입을 갖는 형태로 typedef 를 해줘야 한다.
전자의 typedef 를 하는 것보다는 이미 존재하는 타입을 사용한 #ifdef 방식이 더 좋다고 한다. (그러고보니 좋은 거 같다.. --)

// ok but not recommended

// typedef에 의한 문자열  
typedef basic_string〈TCHAR,  char_traits〈TCHAR〉,  allocator〈TCHAR〉〉 tstring;  

// better, recommended

// 매크고에 의한 선택적 문자열  
#ifdef _UNICODE  
#define tstring wstring  
#else  
#define tstring string  
#endif

see also:

스트링 길이 문제

프 로그래밍하다보면 문자열을 빈번히 다루게되고 그중에서 문자열 길이를 자주 계산하게 된다. TCHAR로 처리하는 경우 문자열을 그때 마다 개산해야 한다. MFC의 CString이나 STL의 string은 자체적으로 제공되기 때문에 문제는 없으나 TCHAR는 그렇지 않다. 그 부분에 대한 문제를 아래와 같이 제공한다.

  • 문자의 개수 : sizeof(szBuffer) / sizeof(TCHAR)
  • 문자열의 길이 : sizeof(szBuffer) * sizeof(TCHAR)
  • 적절한 매크로를 만들어 사용하면 고민에서 해방될까?

%s 와 %S 차이점

만약 UNICODE 어플리케이션일 경우 %s 는 유니코드 문자열이며 %S 는 ANSI 문자열 포맷팅시 사용된다. 물론 MBCS 일 경우라면 반대가 된다.

반응형