본문 바로가기

강의자료/C/C++

TIP. C++에서 TCHAR 문자열 다루기.


현재 비주얼 스튜디오 2008을 사용하고 있습니다. 하지만 닷넷 컴파일러는 기본값이 UNICODE이기 때문에 예전에 사용하던 MBCS(멀티바이트 문자 집합)방식의 함수들을 쓰기가 애매해졌습니다. 그래서 이제는 TCHAR 타입를 이용해서 문자열을 다루는 방법이 필요합니다. 아니면 wchar_t 타입을 이용해서 UNICODE만을 지원해도 되지만 호환성 유지를 위해 TCHAR를 사용하는게 좋을 것 같습니다.(TCHAR 타입은 컴파일러 셋팅에 따라서 MBCS 또는 UNICODE로 자동 변환됩니다.)

위와 같은 이유때문에 예전에 많이 사용하던 strcpy() 또는 sprintf() 함수를 사용하면 안됩니다. TCHAR 타입을 지원하는 함수를 따로 사용해야 합니다. 그런데 이마저도 보안이 추가되면서 새로운 함수들이 생겨났습니다. 보안은 문자열 길이에 따른 오버플로우를 막아주기 위해 생겨난 듯 합니다만 이 때문에 코드가 좀 더 길어지고 많은 부분을 수정해야 합니다. ㅠㅠ...

그래서 이제는 같은 기능을 하는 함수가 총 6개씩 존재하게 되었습니다.
기본적으로는 char 타입함수, wchar_t 타입함수, TCHAR 타입함수 이렇게 3개가 있고 이것들이 또 보안이 적용되지 않은 함수와 보안이 적용된 함수로 나뉘기 때문에 3X2 = 6개입니다. 같은 역할을 하기 위해 이렇게 많은 함수가 존재하는데 그럼 어떤걸 익혀야 할까요? 저는 TCHAR 타입 방식을 선택하겠습니다. 호환성을 유지시켜주기때문에 어디서든 컴파일이 가능하니까요. 컴파일할 경우 경고메시지를 보지 않기 위해서 보안이 적용된 함수를 사용하도록 하겟습니다.

서론이 너무 길었던 것 같습니다. 우리에게 필요한 건 사용법, 그 이상도 이하도 아닙니다. 그럼 예제코드를 한번 봅시다.

1. 우선 간단한 문자열 복사( strcpy() 함수 역할 ) 입니다.

TCHAR szName[128] = "하얀뱀";
TCHAR szNewName[128];

_tcscpy_s(szNewName, _countof(szNewName), szName);


위 코드에서 보다시피 _tcscpy_s() 함수가 사용되었습니다. _t는 TCHAR를 사용한다는 것을 의미하고 마지막의 _s는 보안이 적용된 함수임을 의미합니다. 그리고 또하나 새로운 함수가 보입니다. 바로 _countof() 입니다. 이 함수는 입력가능한 문자열의 최대개수를 반환해줍니다.

다시 말해서, _countof(szNewName) 은 sizeof(szNewName)/sizeof(TCHAR) 를 의미한다고 보시면 됩니다.

2. 다음은 문자열 입력 ( sprintf() 함수 역할 )에 대해서 알아보겠습니다.

TCHAR szName[128] = "하얀뱀";
TCHAR szNewName[128];

_stprintf_s(szNewName, _countof(szNewName), _T("나는 %s 입니다."), szName);


여기서는 _stprintf_s() 함수가 사용되었습니다. 이 함수의 이름도 역시 잘 살펴보면 t 와 s 가 추가되어서 TCHAR타입을 사용하고 보안이 적용된 함수라는 것을 알 수가 있습니다.

이 2가지 함수만 알아도 문자열을 다루는데 불편함이 없을 겁니다. 물론 string 클래스가 더 좋겠지만 string 클래스를 사용할 수 없는 환경에서는 어쩔 수 없이 써야하기 때문에 기본적으로 알고 있어야 합니다. ^^

추가로 StringCchPrintf라는 함수에 대해서 더 알아보고 넘어가도록 하겠습니다. 이 함수는 _stprintf_s와 같은 역할을 하는 함수입니다. 단, _stprintf_s함수는 입력하려는 문자열의 길이가 입력받을 문자열 변수의 길이를 초과할 경우 에러를 나타내게 되지만 StringCchPrintf는 초과하는 부분만큼을 잘라버리고 변수에 문자열을 입력하는 차이점이 있을 뿐입니다.

TCHAR szName[128] = "하얀뱀";
TCHAR szNewName[128];

// 이 함수를 사용하시려면 strsafe.h 헤더파일을 추가하여야 합니다.
StringCchPrintf(szNewName, _countof(szNewName), _T("나는 %s 입니다."), szName);


보시다시피 사용법은 완전히 동일합니다. 단지, 예외상황을 체크해야할 필요가 있을 경우 _stprintf_s를 사용하고 그냥 무시하고 넘어가도 될 경우에는 StringCchPrintf 를 사용하시면 됩니다.

3. 다음은 문자열 길이 ( strlen() 함수 역할 )에 대해서 알아보겠습니다.

char szName[128] = "하얀뱀";
int length = strlen(szName);            // char 버전.

TCHAR szName[128] = "하얀뱀";
int length = _tcslen(szName);         // TCHAR 버전.

wchar_t szName[128] = "하얀뱀";
int length = wcslen(szName);         // wchar_t 버전.


이전 버전의 함수와 비교시 함수명만 바뀌었을 뿐 사용법은 동일합니다. 사용하는 문자열에 따라서 함수를 골라서 사용하시기만 하면 됩니다. ^^

오늘은 여기까지만 작성하겠습니다. 추가적인 내용이 필요하면 여기에 수정하여 내용을 덧붙이도록 하겠습니다.