본문 바로가기
Study/C++

각종 문자열 바꾸기~~

by 뿡뿡대마왕 2011. 3. 30.
반응형

1. http://blog.naver.com/cbdman/130032675221
   ( 이곳에 가면 문자열 바꾸는 팁이 있당..~)

2. 출처: http://blog.naver.com/jingyoohan?Redirect=Log&logNo=40112777485

 
Win32 프로젝트에서 기본 인코딩을 유니코드로 작업하던 중 네트워크 카드에 할당된 IP주소를 구할 일이 생겼다. IPHLPAPI.LIB 라이브러리의 GetAdaptersInfo()함수를 사용하면 간단하게 IP주소를 구할 수 있다. 하지만 이 함수는 IP_ADAPTER_INFO 구조체를 통해 IP주소를 전달하는데, 이 구조체의 IpAddressList.IpAddress.String 멤버는 char형으로 정의되어 있다. 그러므로 char를 유니코드로 변환할 필요가 생긴다.

 

 다행이 API차원에서 형변환 함수 MultiByteToWideChar()과 WideCharToMultiByte()를 제공하므로 쉽게 변환할 수 있다. 아래에 간단한 예제를 작성해 놓았다.

 

char -> wchar 변환

 

TCHAR ipaddr[16];
memset(ipaddr,'\0',sizeof(TCHAR)*16);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED,

          pAdapterInfo->IpAddressList.IpAddress.String, 
          _tcslen(pAdapterInfo->IpAddressList.IpAddress.String), ipaddr, 16);

좀더 보충하자면 아래것이 더 보기가 좋았어~!!

char sTime[] = '유니코드 변환 예제';
  BSTR bstr;
  // sTime을 유니코드로 변환하기에 앞서 먼저 그것의 유니코드에서의 길이를 알아야 한다.
  int nLen = MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), NULL, NULL)
  // 얻어낸 길이만큼 메모리를 할당한다.
  bstr = SysAllocStringLen(NULL, nLen);
  // 이제 변환을 수행한다.
  MultiByteToWideChar(CP_ACP, 0, sTime, lstrlen(sTime), bstr, nLen);
[출처] MultiByteToWideChar // WideCharToMultiByte|작성자 챵층난쿈 

 


wchar -> char 변환

 

TCHAR unicode[30]=L"테스트입니다.";
int len = 256; 
char str[256];

WideCharToMultiByte(CP_ACP, 0, unicode, len, str, len, NULL, NULL);

 

(추가 내용)

윈도7에서 간단한 메시지를 리눅스(CentOS 5.3)에 전송할 일이 생겼다. 리눅스에는 간단히 C로 메시지 수신 서버를 작성하고 윈도에는 VC2010 express를 이용해 인코딩 후 테스트를 했다.

먼저, 간단하게 echo메시지를 날려보니 전달한 한글 내용이 정확하게 리턴되어 '잘 돌아가는 군..' 이라고 생각했다가 리눅스쪽을 살펴보니 한글이 다 깨져 있는 것이다.

 

결론은 한글 인코딩 문제. 윈도는 기본적으로 ANSI 인코딩(CP949)을 사용하고 CentOS는 UTF-8을 사용하므로 호환이 되지 않는 것이다. 이제 필요한 것은 ANSI 와 UTF-8의 상호 변환 C코드. 이를 알아보자

 

ANSI와 UTF-8은 기본적으로 호환되지 않는다. 하지만 모두 UNICODE와 호환되므로 이를 이용하면 된다.

 

ANSI <-> UNICODE

위에서 설명한 것처럼 MultiByteToWideChar(),WideCharToMultiByte() 함수를 이용한다.

 

UNICODE -> UTF-8

WideCharToMultiByte(CP_UTF8, 0, unicode /* WCHAR* 버퍼*/, -1, utf8 /* char* 버퍼*/, sizeof(utf8), NULL, NULL);

 

UNICODE <- UTF-8

MultiByteToWideChar(CP_UTF8, 0, utf8 /* char* 버퍼*/, -1, unicode /* WCHAR* 버퍼*/, strlen(utf8)*2);

 

통합한 코드는 아래와 같다.

 

char* ansi_to_utf8(char* ansi) 

    WCHAR unicode[1500]; 
    char utf8[1500]; 
 
    memset(unicode, 0, sizeof(unicode)); 
    memset(utf8, 0, sizeof(utf8)); 
 
    ::MultiByteToWideChar(CP_ACP, 0, ansi, -1, unicode, sizeof(unicode)); 
    ::WideCharToMultiByte(CP_UTF8, 0, unicode, -1, utf8, sizeof(utf8), NULL, NULL); 
 
    return utf8;
}
char* utf8_to_ansi(char *utf8) 

    WCHAR *unicode = NULL; 
    char *ansi = NULL; 
 
    unicode = (WCHAR*)calloc(1, strlen(utf8)*2);
    ::MultiByteToWideChar(CP_UTF8, 0, utf8, -1, unicode, strlen(utf8)*2);
 
    //ansi = (char*)calloc(1, _tcslen(unicode)*2);
    ansi = (char*)calloc(1, wcslen(unicode)*2);  /* 테스트한 프로젝트의 문자 집합 속성이 MultiByte 이므로 _tcslen()은 strlen()으로 정의된다. strlen()은 char*을 인자로 받으므로 컴파일 오류가 생긴다. */
    //::WideCharToMultiByte(CP_ACP, 0, unicode, -1, ansi, _tcslen(unicode)*2, NULL, NULL); 
    ::WideCharToMultiByte(CP_ACP, 0, unicode, -1, ansi, wcslen(unicode)*2, NULL, NULL); 
 
    return ansi; 
}

참고: VC++ 에서 문자집합 표기



 


반응형

댓글