꼮꼮읽어보기

http://bektekk.wo.to/

'and so on > 문자열' 카테고리의 다른 글

CString 사용  (0) 2013.01.31
msdn  (0) 2012.12.18
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10

msdn

http://msdn.microsoft.com/en-us/library/ms235631(v=vs.80).aspx

'and so on > 문자열' 카테고리의 다른 글

CString 사용  (0) 2013.01.31
꼮꼮읽어보기  (0) 2012.12.20
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10

UTF-8, UNICODE, ANSI - 인코딩에 대하여


 http://blog.naver.com/declspec?Redirect=Log&logNo=10092640244

'and so on > 문자열' 카테고리의 다른 글

꼮꼮읽어보기  (0) 2012.12.20
msdn  (0) 2012.12.18
멀티/유니->utf8, utf8->멀티/유니  (0) 2012.12.10
형변환 주의하기  (0) 2012.12.10
[문자열] 아스키코드, 멀티바이트, 유니코드  (0) 2012.12.10

멀티/유니->utf8, utf8->멀티/유니

    const char* uni_to_utf8(const wchar_t* unicode)
    {
      static CString utf8;
      size_t len = wcslen(unicode);
      int szutf8 = WideCharToMultiByte(CP_UTF8, 0, unicode, len,  utf8.GetBufferSetLength( len * 4 ), len*4, 0, 0);
      utf8.GetBufferSetLength( szutf8 );
      return utf8.GetString();
    }
    
    const wchar_t* utf8_to_uni(const char* utf8)
    {
      static CStringW unicode;
      unicode.Empty();
      size_t len = strlen(utf8);
      int szuni = MultiByteToWideChar(CP_UTF8, 0, utf8, len, unicode.GetBufferSetLength(len), len);
      return  unicode.GetBufferSetLength(szuni);
    }
    
    const char* ansi_to_utf8(const char* ansi)
    {
      return uni_to_utf8 (CStringW(ansi));
    }
    
    const char* utf8_to_ansi(const char* utf8)
    {
      static CString ansi;
      ansi.Empty();
      ansi = utf8_to_uni(utf8);
      return ansi;
    }

'and so on > 문자열' 카테고리의 다른 글

msdn  (0) 2012.12.18
UTF-8, UNICODE, ANSI - 인코딩에 대하여  (0) 2012.12.18
형변환 주의하기  (0) 2012.12.10
[문자열] 아스키코드, 멀티바이트, 유니코드  (0) 2012.12.10
wchar -> char -> String  (0) 2012.10.31

형변환 주의하기

        1. 유니코드/멀티바이트 형변환은 절대로 하지마세요

    2. 어쩔수 없이 해야 된다면 ATL 스트링으로 캐스팅을 하세요




2. 설명

멀티바이트 -> 유니코드
    

    const char* str = "...";
    const wchar_t* wstr = CStringW ( str );


    근데 CStringW  부분에

    근데 CStringW  부분에 ToWideStr 이런거 집어넣으시면 안됩니다.




    유니코드 -> 멀티바이트는

        const wchar_t* wstr = L"...";
         const char* str = CString (wstr);


    CString 대신 WCharToChar 요런거 쓰시면 안되구요
  

  안되는 이유는
    WCharToChar 같은 함수에서 내부적으로
    malloc 을 호출을 하는데
    쓸때없이 메모리를 낭비하는 거라서 안됌





[문자열] 아스키코드, 멀티바이트, 유니코드

※character ser이란?

예전에 미국에서 영어를 표한하기 위해 아스키 코드라는 character set을 만들었다.


character set이란 숫자와 문자의 관계? 또는 문자표 라고 생각하면 된다.


예를 들어 아스키 코드같은 경우에는 char형으로 저장을 하는데

 
char가 문자형이라고 해봐야 일단은 1바이트의 메모리공간으로 메모리에 존재하는 것은 그저 2진수 숫자 뿐이다.


이러한 char로 문자를 표현할 수 있는 이유는 숫자와 문자사이의 표를 만들어 표준으로 정하고 사용하기 때문이다.


예를 들면 숫자 65는 A이다. 숫자 97은 a이다. 이런 형식이다.


참고로, 대문자랑 소문자랑 다른 수 이다. 따라서 A == a 는 거짓이다.




※아스키 코드

char은 8비트로 2의8승-1 로 총 255가지의 숫자를 가지고 있다.


그러므로 아스키 코드는 255가지의 문자를 표현할 수 있을거라 생각할수도 있지만 1비트는 따로 사용하는 용도가 정해져 있다.


그러므로 총 7비트만큼 문자를 표현하는데 사용하고 있다.


아스키 코드표는 외울 필요가 없고, 인터넷에 아스키코드를 검색하면 표를 쉽게 찾을 수 있으니 궁금할때마다 참고 하면된다.




※멀티 바이트 코드

아스키 코드는 1바이트로 문자를 표현한다.(1비트는 어떠한 이유로 사용하지않음)


1바이트는 7비트로 128가지의 문자를 표현하는데 세상의 문자가 128가지는 아니다.


한글도 있고 일본어도 있다. 이러하다보니 1바이트로 처리하기에는 표현할 수 있는 범위가 너무 좁았다.


그 문제점을 해결하기위한 방법중 하나가 멀티 바이트 코드다.


멀티바이트 코드는 영어같은 아스키 코드에 포함되는 문자는 1바이트로 표현하고, 포함되지 않는 문자는 2바이트로 포현한다.


따라서 'abc안녕'와 같은 문자열은 'abc'는 3바이트, '안녕'은 4바이트에 NULL문자 1바이트로 총 8바이트가 할당된다.


얼핏보면 굉장히 효율적인 구조라 할수도 있다.


물론 멀티바이트가 나쁜건 아니지만 몇가지 문제점을 가지고 있다.


영어는 1바이트로 표현하고 한글은 2바이트로 표현하기 때문에 문자열을 다루는 프로그래밍을 할때 코딩이 어렵다.


또한 strlen같은 함수를 사용했을시 한글을 2자리로 인식해서 버그의 소지가있다.


물론 이것을 숙지하고 프로그래밍을 한다면 메모리를 효과적으로 사용할 수는 있겠으나 그것은 프로그래머를 피곤하게 하고 1바이트 문자인지 2바이트 문자인지 체크하는 코드 때문에 성능의 저하가 생길것이다.

따라서 최근 사용되는 character set은 유니코드이다.




※유니코드

유니코드는 멀티바이트와 달리 한글이든 영어든 항상 2바이트의 메모리를 할당한다.


아스키코드의 한계점과 멀티바이트의 문제점을 해결할 수 있는 형태이다.


하지만 이러한 유니코드의 경우에도 문제점이있다.


바로 strlen으로 길이를 조사했을때 'avb하나'를 총 10글자로 인식해버린다. strlen은 아스키 코드 문자열을 위한 함수이기 때문이다.


흔히들 사용해온 printf, scanf등은 전부 아스키코드를 위한 함수였던 것이다.


유니코드 문자열을 위한 입출력 함수는 따로 존재한다. 예를 들면 printf의 유니코드 버전은 wprintf이다.


strlen의 유니코드 버전은 wcslen이고 strcat, strcpy, strcmp, strncpy의 유니코드 버전은 wcscat, wcscpy, wcscmp, wcsncpy이다.


유니코드는 char 형이 아닌 wchar_t형을 사용한다. wchar_t는 unsigned short를 typedef으로 재정의 한 것인데 2바이트다.


또한 유니코드는 일반적인 문자열을 대입해선 안된다.


예를들어 "abc"의 경우 아스키 코드 문자열이다. 유니코드 문자열은 앞에L을 붙여주어야 한다. 예를들어 L"abc"가 유니코드 문자열이다.


windows.h에 재정의 되어있는 WCHAR은 wchar_t이다.


출처

http://hardcoding.egloos.com/557949


F5 실행 Ctrl F5 결과 값 차이 발생

F5는 디버깅 모드로 시작

Ctrl+F5는 디버깅 모드 하지 않고 시작


인데 문제가 발생했다 


F5로 하면 실행이 잘되고

Ctrl+F5로 하면 원하는 값이 나오지 않는 것이다


검색해보니

초기화 문제가 발생 해서 나타났다고 

어떤 사람이 비슷한 질문을 올렸다 

휴 찾았다 그래도 


그리고 추가 답변


F5는 그냥 실행되는 것이고 
Ctrl + F5는 메모리 침범이 일어났을 경우에 어느정도 더미를 붙여 놓아서 메모리 에러가 발생되지 
않도록 하는 기능을 합니다.(VC++에서 지원)그러니까 F5와 Ctrl + F5를 실행시켰을 때 결과가 다르 
다면 자신의 코드중에 메모리 관련 실수를 했다는 것을 추론할 수 있죠. 덤으로 Debug와 Realse와는 
좀 많이 다릅니다. 돈주는 파는거라면 최종 버전은 언제나 Release버전으로 해야죠. ^^



질문 출처

http://www.gpgstudy.com/forum/viewtopic.php?t=9179





'and so on > error' 카테고리의 다른 글

RegisterTaskDefinition 80070534 error  (0) 2014.03.04
버그. 에러, 예외  (0) 2013.01.25
[SVN] checkout 하기  (0) 2012.12.04
[LNK2001] 외부 기호를 확인할 수 없습니다.  (0) 2012.11.26
[LNK2019] inet_addr 사용 오류  (0) 2012.10.18

[SVN] checkout 하기




1.svn에 등록되어 있는 아무 프로젝트를 연다


2.  [보기] -[Repository Explorer] 선택




3. 체크 아웃 원하는 폴더 선택 후  버튼 누르기


4. 원하는 경로 적으면 완료


[LNK2001] 외부 기호를 확인할 수 없습니다.

헤더 파일에 


전역변수를 extern 으로 선언 하고 ( 정의는 하지 않은 상태) 


- test.h

 #ifndef __TEST__

#define __TEST__


#include <Windows.h>

#ifdef EXT_GLOBAL

#define EXT

#else

#define EXT extern

#endif


EXT HINSTANCE hInst;


함수들 선언 


#endif



.cpp 에서 정의를 하지 않았을때 발생하는 오류 


.cpp에서 hInst를 정의 해주면 된다.


- test.cpp

 HINSTANCE hInst = NULL;




wchar -> char -> String


  • wchar -> char로 문자열을 변환 하려고 하는데,
    인터넷에서 찾은 함수는 메모리 할당하고 해제 해주지 않고 
    그 메모리를 포인터로 넘겨줘서 메모리 사용에 좋지 못할 것 같아서 수정하였다.

  • 함수 WCharToChar,  ToUTF8Str 두개 사용 

  • 메모리를 할당 받아서 WCharToChar 함수로 포인터 넘겨줌 



  // wchar -> char

void WCharToChar(const wchar_t* pwstrSrc, char * pstr)

{

setlocale(LC_ALL, "korean"); 

assert(pwstrSrc);


#if !defined _DEBUG

int len = 0;

len = (wcslen(pwstrSrc) + 1)*2;

char* pstr      = (char*) malloc ( sizeof( char) * len);


WideCharToMultiByte( 949, 0, pwstrSrc, -1, pstr, len, NULL, NULL);

#else

int nLen = wcslen(pwstrSrc);

int count = 0;


count = wcstombs(pstr, pwstrSrc, nLen+1); // 여기서 와이드에서 멀티 바이트로 변환

#endif

}



  std::string ToUTF8Str(const WCHAR *S, const int NumChars)

{

std::string Result = "";

int BufferLen = NumChars + 1;


char* pstr      = (char*) malloc ( sizeof( char) * BufferLen + 1);


WCharToChar(S, pstr); // 여기서 호출 해서 


Result.assign(pstr); // String 으로 변환 해준 후 

free(pstr);            // 메모리 해제 


return Result;

}



만약 wcstombs() 사용하는데 뒤에 부분이 잘린다면 

pstr의 크기를 2배로 늘려주면 됨 

버퍼 크기 문제였음ㅜㅜ


문자열 짜잉나 !!