유니코드 L"" 문자열 & 코드페이지
2005/01/08 21:28
L"" 을 사용하여 L"한글"과 같이 표기하면 유니코드 상수 문자열을 나타내주는 것은 다들 쉽게 알고 있는 사실입니다. 즉 MBCS(싱글바이트 문자열인 ASCII나 더블바이트 문자열인 한글,일어,중어 등등) 상수 문자열을 MSVC 컴파일러의 전처리기에서 해당하는 유니코드 상수 문자열로 인코딩해줍니다.

예를 들자면
"test" 라는 4바이트 크기의 싱글바이트 문자열, L"test" 와 같이 표기하면 8바이트 크기의 유니코드 문자열입니다.
"한글" 이라는 4바이트 크기의 더블바이트 문자열, L"한글"과 같이 표기하면 4바이트 크기의 유니코드 문자열입니다.

그런데 이렇게 L"" 표기를 사용하여 컴파일러 전처리기가 MBC 문자열을 유니코드로 인코딩할 때 전처리기가 사용할 코드 페이지를 제대로 정해 주어야지만 옳바른 유니코드 인코딩이 이루어 지는 것은 의외로 잘 알려지지 않은 사실입니다. 저 같은 경우는 뒤에서 설명드릴 문제로 인해서 굉장히 고생한적이 있었고 오늘에서야 여기 질/답란을 통해서 이 사실을 알게되었습니다. 다른 분들도 혹시 비슷한 경우를 겪으실지 모르기에 이렇게 팁으로 올리고자 합니다.

전처리기가 L"" 상수 문자열을 인코딩할 때 사용할 코드페이지를 지정하기 위해서는

#pragma locale ("[locale-string]")

을 사용하면 됩니다. 즉 한글 상수 문자열이 필요하면 #pragma locale ("Korean") 또는 #pragma locale ("kor") 같이 선언해주면 컴파일러의 전처리기에 의해서 L"한글"이 대응하는 유니코드 상수 문자열로 인코딩 됩니다.
만약 #pragma locale () 이 사용되지 않았을 경우에는 디폴트 설정에 의하여 인코딩에 사용되는 코드 페이지가 결정됩니다. 이 때 디폴트 설정은 제어판/지역설정/standards and formats에서 설정된 값을 참조하는것 같습니다. 한글 윈도의 경우 기본적으로 한글(Korean)로 되어 있을 것이고 영문 윈도를 사용하시는 경우에도 한국 사람인 경우 이 설정을 Korean으로 하는게 보통이기에 대부분의 한국 프로그래머에게 있어서 특별히 #pragma setlocale () 을 사용하지 않아도 L"한글"과 같은 한글 상수 문자열이 대응하는 유니코드 상수 문자열로 옳바르게 인코딩 되어집니다.

그러나 만약 영문 윈도 환경에서 위에 설명한 지역 설정(locale)이 English인 경우 (영문 윈도 디폴트 설정) 전처리가 사용하는 코드 페이지는 #pragam locale ("C")를 사용한 것과 같아지며 이 경우 L"한글"이라고 코딩 된 문자열 상수는 전처리기가 유니코드로 인코딩 한 후에 전혀 엉뚱한 결과를 가지게 됩니다. "한글"이라는 MBC 문자열은 메모리 구조상 "C7 D1 B1 DB 00"와 같이 표현되고 이에 대응하는 유니코드 문자열 L"한글"의 메모리 구조는 "5C D5 00 AE 00 00" 와 같이 표현되어야 하지만 위와 같이 지역 설정이 English 로 되어 있고 프로그램 소스에서 #pragma setlocale ("Korean") 이 사용되지 않았다면 전처리기가 인코딩한 문자열의 메모리 구조는 "C7 00 D1 00 B1 00 DB 00 00 00" 와 같이 표현됩니다. ASCII로 가정하고 단순히 트레일 바이트(Trail Byte) 00을 각각의 바이트에 추가 했다는 것을 볼 수 있습니다.

저의 경우 우연히도 접할 수 있는 모든 컴퓨터가 위의 지역 설정이 한글(Korean)이 아니였었기에 몇 대의 컴퓨터에서 모두 L"한글" 문자열이 제대로 유니코드 인코딩 되지 않는 것을 확인한 후 여기 저기서 L"" 을 사용하여도 MBC 문자열을 유니코드 문자열을 제대로 인코딩 해주지 못한다고 여기 저기 떠들고 다녔었는데 (집안 망신입니다. OTL...) 아마도 비슷한 경우를 당하실 분이 아주 가끔 있을거라 생각합니다. 실재로 멀티 랭귀지를 지원하는 프로그램을 작성 하신다면 보통 문자열이 각각의 코드 페이지를 대표하는 리소스 파일에 저장 되어서 사용되고 이러한 리소스에서 문자열을 읽어 오는 함수는 제대로 유니코드 인코딩된 문자열을 돌려주기 때문에 아주 자주 일어날 상황이 아닐것도 같지만 프로그램을 작성하는 과정에 있어서, 특히 디버깅 과정에서, 변환된 유니코드 문자열이 제대로 인코딩 되었는지 확인하기 위해서 L"" 문자열을 사용하여 비교하는 경우가 종종 발생하고 이 때 코드 페이지 설정이 제대로 되어 있지 않다면 이유도 모른채 제대로 변환된 유니코드가 제대로 변환되지 않는다고 불평해야 하는 사태가 발생할 수도 있습니다. 제가 그랬습니다. TT. 또는 메세지 박스를 ::MessageBoxW(NULL, L"한글 메세지", ...); 를 사용하여 메세지를 출력했는데 이상한 문자가 표시되는 것을 볼 지도 모릅니다.

아마도 같은 더블바이트 문자셋인 중국어나 일본어를 지원하는 프로그램을 작성하시다 보면 특히 이런 사태를 경험할 기회를 맞으실지도 모릅니다. 앞에서 설명한 지역 설정이 한글로 되어 있는 경우에 일본어 유니코드 문자열을 L""을 이용하여 표기하고자 하는 경우에 #pragma locale ("Japanese") 를 프로그램 소스에서 선언하거나 또는 지역 설정을 일본어로 바꿔주고 Rebuild All 을 해주시면 됩니다. (Rebuild All을 해줘야하는 이유는 이 지역 설정이 프로그램 컴파일 시 .pch 파일에 저장되는 것 같은데 소스 코드의 변경이 없이 제어판에서 설정만 바꾸는 경우 이러한 변경사항이 반영되지 않겠죠. 따라서 Rebuild All을 해줌으로써 .pch 파일이 다시 생성해줘야 합니다.)

Devpia에서 발췌
http://www.devpia.com/Forum/BoardView.aspx?no=7000&page=1&Tpage=57&forumname=vc_lec&stype=&ctType=&answer=
2005/01/08 21:28 2005/01/08 21:28
Trackback Address :: 이 글에는 트랙백을 보낼 수 없습니다