UNICODE
1988년 애플Apple과 제록스Xerox에 의해 표준화된 문자 셋character set
목차
Character Sets
Single Byte & Double Byte Character Sets
Wide Byte Character Sets (Unicode)
윈도우 운영 체제와 유니코드
유니코드를 지원하는 소스 코드 만들기
변수Variables
문자열text strings
함수functiions
문자열 함수string functions
윈도우 함수windows API
UNICODE 를 고려해서 코딩하는 법
유니코드 스트링 조작 함수
유니코드와 ANSI의 구별
Reference
1 Character Sets
1.1 Single Byte & Double Byte Character Sets
1.2 Wide Byte Character Sets (Unicode)
16 Bit Code | Character | 16 Bit Code | Character |
0000 - 007F | ASCII table | 0300 - 036F | 일반적인 구분 마크들Generic diacritical marks |
0080 - 00FF | 라틴1문자 Latin1 characters | 0400 - 04FF | 키릴어Cyrillic |
0100 - 017F | 유럽형 라틴어European Latin | 0530 - 058F | 영어Armenian |
0180 - 01FF | 확장형 라틴어Extended Latin | 0590 - 05FF | 헤브류어Hebrew |
0250 - 02AF | 표준 음성기호Standard phonetic | 0600 - 06FF | 아라비아어Arabic |
02B0 - 02FF | 수정된 문자들Modified letters | 0900 - 097F | 데이버나거리Devanagari |
2 윈도우 운영 체제와 유니코드
* 윈도우98 : ANSI만 지원
* 윈도우CE : 유니코드만 지원
3 유니코드를 지원하는 소스 코드 만들기
3.1 변수Variables
typedef unsigned short wchar_t; // 유니코드용 문자형
예를 들어, 문자열 버퍼를 다음과 같이 정의할 경우
wchar_t szBuffer[100];
typedef wchat_t TCHAR; // 유니코드 모드로 컴파일할 경우
typedef char TCHAR; // ANSI 모드로 컴파일할 경우
즉, 유저는 문자열 버퍼를 정의하고자 한다면 다음과 같이 쓰면 되는 것이다.
TCHAR szBuffer[100];
문자형 변수뿐 아니라 상수형 문자열 포인터 변수에서도 유니코드를 고려해야 한다.
만약 코드내에서 LPCSTR(const char*)나 LPSTR(char*)와 같은 문자열 포인터 변수를 쓴다면
이 코드는 오직 ANSI 체계만 지원할 수 있게 된다. 이때는 LPCSTR, LPSTR 대신에 각각 LPCTSTR, LPTSTR 형으로 쓰는 것이 유니코드를 대비한 코딩이 될 수 있다.
결론은, 문자형 및 문자열 포인터는 다음의 형으로 쓰도록 한다.
type | ANSI | UNICODE | Generic |
character | char | wchar_t | TCHAR |
character pointer | PSTR, 0LPSTR | PWSTR, LPWSTR | PTSTR, LPTSTR |
constant character pointer | PCSTR, LPCSTR | PCWSTR, LPCWSTR | PCTSTR, LPCTSTR |
3.2 문자열text strings
TCHAR *szError = "Error";
TCHAR *szError = L"Error";
TCHAR *szError = _TEXT("Error");
if (szError[0] == _TEXT('j')) {
....
}
참고로 _TEXT 매크로는 UNICODE로 컴파일 할 때는 다음과 같이 정의 된다.
#define _TEXT(x) L##x
#define _TEXT(x) x
_TEXT 매크로는 win32 API 환경에서 쓰는 매크로이며 만약 MFC 환경에서 컴파일 한다면 _TEXT 매크로와 더블어 _T 매크로도 쓸 수 있다.
TCHAR *szError = _T("Error"); // MFC 환경이라면...
문자열string
Win32 API | MFC |
_TEXT("abc") | _TEXT("abc"), _T("abc") |
3.3 함수functiions
3.3.1 문자열 함수string functions
char *strcat(char*, const char*);
wchar_t *wcscat(wchar_t*, const wchar_t*);
char* strchar(const char*, int);
wchar_t* wcschar(const wchar_t*, wchar_t);
char* strcpy(char*, const char*);
wchar_t wcscpy(wchar_t*, const wchar_t*);
size_t strlen(const char*);
size_t wcslen(const wchar_t*);
그러나 위의 함수들을 쓰려면 같은 동작을 수행하는 모듈에서 ANSI용과 유니코드용 코드를 따로 작성해야 할 것이다. 변수와 문자열과 마찬가지로 ANSI와 유니코드 모두를 한 코드에서 컴파일이 가능하도록 하려면 str이나 wcs가 들어가는 자리에 _tcs를 붙이면 된다.
TCHAR* _tcscat(TCHAR*, const TCHAR*);
TCHAR* _tcschar(const TCHAR*, TCHAR);
TCHAR* _tcscpy(TCHAR*, const TCHAR*);
size_t _tcslen(const TCHAR*);
..........
3.3.2 윈도우 함수windows API
참고로 윈도우 API에서 끝에 대문자 W가 붙는 것은 Wide를 나타내며 유니코드 스트링을 위한 버전이고 A가 붙는 것은 ANSI 스트링을 받는 함수이다. 윈도우 라이브러리 내부에는 다음과 같이 코딩이 되어 있다.
#ifdef UNICODE
#define CreateWindowEx CreateWindowExW
#else
#define CreateWindowEx CreateWindowExA
4 UNICODE 를 고려해서 코딩하는 법
* 바이트, 바이트 포인터, 데이타 버퍼를 이용할 땐 BYTE, PBYTE와 같은 explicit data type을 사용한다.
* literal 문자와 스트링에 _TEXT, _T 와 같은 매크로를 사용한다.
* 문자를 바이트로 인식하는 오류를 범하지 않는다. 예를 들어 문자열 버퍼에 있는 문자수를 계산할 때 sizeof(szBuf)와 같이 쓰면 안되고, 'sizeof(szBuf)/sizeof(TCHAR)와 같이 써야 한다. 그리고 메모리를 문자 수대로 할당하고자 할 때 malloc(nCharacter)'가 아니고 malloc(nCharacter*sizeof(TCHAR))로 호출해야 한다.
5 유니코드 스트링 조작 함수
함수명 | 기능 |
lstrcat | 스트링을 다른 스트링의 끝에 연결 |
lstrcmp | 대소문자를 구별해서 두개의 스트링을 비교 |
lstrcmpi | 대소문자를 구별하지 않고 스트링을 비교 |
lstrcpy | 두 개의 스트링을 카피 |
lstrlen | 스트링의 길이를 리턴 |
참고로 언어별 스트링을 비교하는 함수로 다음과 같은 API가 제공되고 있다.
int CompareString(LCID lcid, DWORD fdwStyle, PCWSTR pString1, int cch1, PCTSTR pString2, int cch2);
마지막으로 printf 함수는 소스를 _UNICODE 매크로를 정의하여 컴파일하면 printf에 전달되는 모든 문자와 스트링은 유니코드로 표현되고 _UNICODE 매크로를 정의하지 않고 컴파일하면 파라미터의 스트링은 ANSI로 인식하게 된다.
그러나 formatted data를 다루는 sprintf계열의 함수는 유니코드와 ANSI용이 분리되어 있다.
ANSI | UNICODE | Generic | Window API |
sprintf | swprintf | _stprintf | wsprintf |
각각의 함수가 쓰이는 예제는 다음과 같다.
char szA[100]; // ANSI 스트링 버퍼
char szW[100]; // 유니코드 스트링 버퍼
sprintf(szA, "%s", "ANSI string"); // 일반적인 ANSI 스트링을 표현할 때
sprintf(szA, "%s", L"Unicode string"); // 유니코드 문자열을 ANSI로 변환
swprintf(szW, L"%s", L"Unicode string"); // 유니코드 스트링을 표현할 때
swprintf(szW, L"%s", "ANSI string"); // ANIS 스트링을 유니코드 스트링으로 변환
6 유니코드와 ANSI의 구별
DWORD IsTextUnicode(CONST PVOID pvBuffer, int cb, PINT pResult);
'IT_Programming > MFC · API' 카테고리의 다른 글
[API] WIN32 API에서 ODBC (오라클,MS-SQL,MDB) 사용하기 - CQuery Class (0) | 2009.08.09 |
---|---|
[API] 더블 버퍼링 스크롤바 테스트! (0) | 2009.08.04 |
[API] 슈퍼 클래싱 (Super Classing) (0) | 2009.07.29 |
[API] 서브 클래싱( SUB CLASSING ) (0) | 2009.07.29 |
[API] 사용자 정의 메시지 핸들러 & 메시지 크래커 (0) | 2009.07.29 |