C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[58855] Re:Re:Re:Re:Re:Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요)
김상구.패패루 [peperu] 2005 읽음    2009-10-21 16:34
AnsiString은 안전합니다. 마음놓고 쓰셔도 됩니다. 문제는 WideString이죠.
WideString은 원래 목적이 유니코드 지원이 아니라 OLE 스트링 지원으로 탄생한 클래스입니다. 유니코드를 지원하긴 하지만 기본적으로 BSTR을 취급하기 위한게 원래 목적이란거죠.

일단.. 유니코드를 사용하실 땐 공통적으로 소스코드도 유니코드(UTF8이나 UTF16)로 저장하실것을 권장합니다.

WideString s;
1.  s = "안녕하세요"; // 문제 없지만 권장하지 않습니다. ANSI->UTF16 코드변환이 자동으로 이루어지긴 하지만
                           // 다른 언어환경의 OS에서 실행하면 s에 엉뚱한 값이 들어가겠죠.
2.  s = L"안녕하세요"; // 심각하게 문제있습니다. WideString의 = 연산자는 BSTR 타입을 요구하기 때문입니다.
3.  s = WideString(L"안녕하세요);  //  안전한 방법이지만 메모리 복사가 이루어집니다.
4.  WideString s1 = L"안녕하세요";  // 가장 안전하고 성능에도 영향이 없습니다.
5.  WideString s2(L"안녕하세요");  // 4번과 동일하죠. 표현만 다를 뿐.

기본적으로 WideString은 레퍼런스카운트 관리가 없기 때문에 대입 연산시 메모리 복사가 일어납니다. 메모리 복사 없이 대입이 되는 경우는 BSTR타입의 문자열이 대입될 때 뿐이죠. 그래서 2009 이하 버전이 유니코드를 지원하면서도 제대로 지원하지 못한다고밖에 볼 수 없었던겁니다.
UnicodeString을 사용하시는 경우엔 이런 문제가 전혀 없지만 그래도 1번의 예제는 피하시는게 좋습니다. 이유는 동일합니다. 소스코드 안에 직접 문자열을 넣는 것을 가급적 피하시는것을 권장하지만 귀차니즘이 발동할 때에는 반드시 L이나 U를 앞에 붙여주시는게 성능면에서도 호환성면에서도 좋습니다. L이나 U가 없으면 런타임시 매번 코드변환이 일어나겠죠.


아제나 님이 쓰신 글 :
: WideString s;
: s = L"감사합니다';
:
: 이 문장이 메모리 오류가 발생하나요?
: 이런~
: 여태 아무 생각 없이 써왔는데요... ㅠㅠ
:
: WideString s;
: AnsiString p = "감사합니다";
: s = p;
: 이 문장은 문제없겠죠?
:
: 음~!!!
:
: 김상구.패패루 님이 쓰신 글 :
: : 아마 사용중인 C++ Builder가 2009미만 버전인 듯 하군요.
: : UnicodeString은 2009부터 지원되는 VCL의 기본 문자열 클래스입니다.
: : 그 이하 버전을 사용중이시라면 WideString을 이용하실 수 있지만 주의하셔야 하는게...
: :
: : WideString s = L"감사합니다";
: : 이렇게 쓰시는 건 괜찮지만
: :
: : WideString s;
: : s = L"감사합니다";
: :
: : 이렇게 쓰시는건 절대 안됩니다. 그 이유는 처음 예제는 생성자로 초기화 되지만 두번째 예제는 생성자가 아닌 BSTR 문자열 대입으로 처리되기 때문에 메모리 에러가 발생하게 됩니다. 물론 Edit1->Text = L"어쩌구"; 이런 식으로 쓰셔도 문제가 되는게... 2009 이전의 VCL클래스들은 AnsiString기반이기 때문에 아무리 L을 붙여서 유니코드로 지정해도 실제 대입은 Ansi로 컨버전 되기 때문입니다.
: : 2009 이전 버전에서 유니코드를 사용하시려면 Tnt Unicode Component를 이용하셔야 하고 이 경우 모든 스트링 타입 프라퍼티는 모두 AnsiString이 아닌 WideString타입이 됩니다.
: :
: : 향후 프로젝트 마이그레이션을 생각하신다면 2009 이상의 버전으로 진행하심이 편할겁니다.
: :
: :
: : 궁금이 님이 쓰신 글 :
: : : 성의있는 답변에 또또 감사요~ (_._)
: : : 저는 그냥 AnsiString 으로 Edit의 text 값을 보내서 그런값들이 들어갔던거군요.. ^^
: : : 근데 지금 UnicodeString sU = L"감사합니다"; // UTF-16  <-- 이걸로 컴파일 해보려니
: : :
: : : Undefined symbol 'UnicodeString'  <-- 이런 에러가 나는데... include시켜야하는 헤더라고 있나요?
: : : 한글쪽으론 해본적이 없어서뤼 ....
: : :
: : : 영어나 한글이외의 특수문자들도 섞여서 Edit->Text 에 입력할경우
: : : Edit->Text 에 입력한 스트링을 UnicodeString 으로 받으려면 어떻게 해야하는지요 -.-;;
: : :
: : :
: : : 님덕에 조금씩 희망을 얻고있습니다...
: : :
: : : 아! 그리고 영어보다 한글이 훨씬 훨씬 많이 쓰일 예정이라 이런식으로 해야할듯합니다
: : : -------------------------------------
: : :
: : :
: : : 김상구.패패루 님이 쓰신 글 :
: : : : ^^ 이번엔 훨씬 알기쉽게 질문을 하셨네요.
: : : : 즉슨, 유니코드 문자 코드로부터 초중종성 값을 얻고싶으신거군요.
: : : :
: : : : 다음 두 코드를 보세요.
: : : : UnicodeString sU = L"감사합니다"; // UTF-16
: : : : AnsiString sA = "감사합니다"; // 완성형코드
: : : :
: : : : 실제 내용을 브레이크포인트를 걸어 조사해 보면
: : : : sU: AC10   C0AC   D569   B2C8   B2E4
: : : : sA: B0A8   BBE7   C7D5   B4CF   B4D9
: : : :
: : : : 즉... 님이 말씀하신 B0A8은 유니코드값이 아닌 완성형 코드입니다. 자모 분석을 하시려면 UnicodeString에 대입을 하시면 되고 바이트 단위로 얻는건 현재 사용하는 방법으로 하셔도 되겠고
: : : : BYTE *pStr = (BYTE*)sU.w_str();
: : : : 이런식으로 포인터를 얻어 스캔해 보셔도 되겠네요.
: : : :
: : : : 한가지 첨언을 하자면 전송하는 데이터에 한글보다 영어가 압도적으로 많다면 굳이 영어인지 한글인지 구분하는 루틴을 넣는 것 보다는 UTF-8로 인코딩해서 전송하는 편이 깔끔할겁니다.
: : : :
: : : :
: : : : 궁금이 님이 쓰신 글 :
: : : : : 우선 답변 감사합니다
: : : : : 질문을 님 말씀대로 좀 정리해야겠네요...
: : : : :
: : : : : 1. 아래처럼 조합형으로 만들어진 유니코드입니다.
: : : : : ================================================
: : : : : 유니코드 2.0의 한글 코드
: : : : : 한글 음절: 0xAC00 ~ 0xD7A3 (11172 자)
: : : : :
: : : : : V = {[(Cho_i X 21)+ Jung_i]*28}+ Jong_i + 0xAC00
: : : : : V : 유니코드 값 Cho_i: 초성 인덱스값 Jung_i : 중성 인덱스값 Jong_i : 종성 인덱스 값
: : : : :
: : : : : 조합형 코드: 초성(19개) × 중성(21개) × 종성(28개)
: : : : : → 자모 조합과 자모 분리가 용이하다.
: : : : : 모든 현대 한글 표현 가능 (KS-C-5601의 한글 음절 모두 포함)
: : : : : 유니코드 2.0은 유니코드 1.1과 한글 표현 방식이 달라서 서로 호환되지 않는다.
: : : : : 부코드  0  1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  24  25  26  27   
: : : : : 초성  ㄱ  ㄲ  ㄴ  ㄷ  ㄸ  ㄹ  ㅁ  ㅂ  ㅃ  ㅅ  ㅆ  ㅇ  ㅈ  ㅉ  ㅊ  ㅋ  ㅌ  ㅍ  ㅎ   
: : : : : 중성 ㅏ  ㅐ ㅑ  ㅒ  ㅓ  ㅔ  ㅕ  ㅖ  ㅗ  ㅘ  ㅙ  ㅚ  ㅛ  ㅜ  ㅝ  ㅞ  ㅟ  ㅠ  ㅡ  ㅢ  ㅣ 
: : : : : 종성  없음  ㄱ  ㄲ  ㄳ  ㄴ  ㄵ  ㄶ  ㄷ  ㄹ  ㄺ  ㄻ  ㄼ  ㄽ  ㄾ  ㄿ  ㅀ  ㅁ  ㅂ  ㅄ  ㅅ  ㅆ  ㅇ  ㅈ  ㅊ  ㅋ  ㅌ
: : : : :  ===============================================
: : : : : 2. 위 처럼 제가 Edit에 쓴 글자 하나하나에 대한 값을 얻고 싶습니다.
: : : : : ex)
: : : : : : : 감 : AC 10  =>{[(0 X 21)+ 0]*28}+ 16 + 0xAC00 = 44048
: : : : : : : 사 : C0 AC => 49324
: : : : : : : 합 : D5 69  => 54633
: : : : : : : 니 : B2 C8 => 45768
: : : : : : : 다 : B2 E4 => 45796
: : : : :
: : : : : 3. 위 값을 byte 형으로  받고 싶어요
: : : : : ex) 감 :    Buff[0] = HIBYTE(44048);   <== 0xAC
: : : : :     Buff[1] = LOBYTE(44048);  <== 0x10
: : : : :
: : : : : 4. 위처럼 감이란 글씨에 대해서 AC10 이란 값을 원하는데 B0A8 이런 값이 들어가 버리네요...
: : : : :
: : : : : 질문이 너무 길어져버렸네요...
: : : : : 위처럼 하려는 이유는 제가 edit에 쓴 스트링 값을 한글 같은경우 위처럼 유니코드값으로 영어는 해당 아스키값으로 전송하고자 함입니다...
: : : : :
: : : : : 이번에도 너무 제입장으로 글을 썼나요.... -.-;;
: : : : :
: : : : : -------------------------------------------------------------------------------------------------
: : : : :
: : : : : 김상구.패패루 님이 쓰신 글 :
: : : : : : 질문을 이해하기도 어렵게 작성하셔서... 좋은 답글 달리긴 어려워 보이네요. ^^
: : : : : : 질문의 요지가 뭔가요?
: : : : : :
: : : : : : 2009이상 버전을 사용하시고 있다면
: : : : : : Edit1->Text = L"감사합니다!ABCD#★←♤";
: : : : : : 혹은
: : : : : : Edit1->Text = U"감사합니다!ABCD#★←♤";
: : : : : :
: : : : : :
: : : : : : 라고만 하셔도 정확하게 UTF-16LE로 저장됩니다. L이나 U를 빼먹지 마세요.
: : : : : :
: : : : : : 참고로... 질문 자체의 문제를 지적하자면
: : : : : : 1. 유니코드라고 하시는데 구체적으로 어떤 인코딩을 말씀하시나요? UTF-16LE? UTF-8? 구체적으로 밝히셔야 합니다.
: : : : : : 2. '이값'이 대체 뭔가요?
: : : : : : 3. 그냥 버퍼란? char 문자열 버퍼를 말씀하시는지 wchar_t 문자열 버퍼를 말씀하시는지
: : : : : : 4. 제대로 들어가지 않는다는게 어떻게 제대로 들어가지 않는다는지... 즉, 기대하고 있던건 어떤 인코딩인데 실제 들어간건 어떤 인코딩인거 같다... 이런식으로...
: : : : : :
: : : : : : 답변 작성자가 님께서 적으신 바이너리값을 각각의 코드표와 일일이 대조해 가면서 답변을 적을만큼 널널할꺼라 생각하시면 오산입니다.
: : : : : :
: : : : : :
: : : : : :
: : : : : : 궁금이 님이 쓰신 글 :
: : : : : : : Edit1->Text = "감사합니다!ABCD#★←♤";   이와 같은값이 들어있다치면
: : : : : : :
: : : : : : : 입력한 스트링값에서 한글은 유니코드로 영문이나 특수문자는 그에 해당하는
: : : : : : :
: : : : : : : 이값을 구하고 싶습니다
: : : : : : :
: : : : : : : 그냥 버퍼에 스트링값을 넣어보니 !표나 ABCD 같은 아스키값은 잘 들어가는데
: : : : : : :
: : : : : : : 한글과 특수문자들의 값이 제대로 들어가질 않습니다
: : : : : : :
: : : : : : : MultiByteToWideChar 를 써보아도 마찬가지네요,,,
: : : : : : :
: : : : : : : 감       사      합       니       다        !   A  B  C  D   #  ★       ←      ♤
: : : : : : : B0 A8 BB E7 C7 D5 B4 CF B4 D9 21 41 42 43 44 23 A1 DA A1 E7 A2 BB    <--- 이런값이 들어가네요
: : : : : : :
: : : : : : : 원하는값은
: : : : : : : 감 : AC 10
: : : : : : : 사 : C0 AC
: : : : : : : 합 : D5 69
: : : : : : : 니 : B2 C8
: : : : : : : 다 : B2 E4     <-- 입니다..
: : : : : : : 특수문자는 유니코드값이 어떻게 되는지 정확한 값을 알수가없네요... 유니코드 구하는 루틴을 함께쓰면되나요??
: : : : : : :
: : : : : : : 하루 종일 삽질하고 있네요 도와주세요

+ -

관련 글 리스트
58837 스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요 궁금이 1244 2009/10/20
58845     Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요 김상구.패패루 1530 2009/10/21
58848         Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요) 궁금이 1686 2009/10/21
58849             Re:Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요) 김상구.패패루 1572 2009/10/21
58850                 Re:Re:Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요) 궁금이 1394 2009/10/21
58853                     Re:Re:Re:Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요) 김상구.패패루 2677 2009/10/21
58854                         Re:Re:Re:Re:Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요) 아제나 1387 2009/10/21
58855                             Re:Re:Re:Re:Re:Re:Re:스트링값을 유니코드값으로 변환하는 방법 좀 알려주세요(재질문이요) 김상구.패패루 2005 2009/10/21
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.