728x90
반응형
음성인식엔진 개발자 출신으로서, 자연어처리/기계번역 분야에서 입력 글자 처리하는 루틴은 상당히 난해한 분야입니다.
프로그램을 보면,
MString 과 UString의 클래스가 있으면, 빈번히 변환한다.
사유 :: 소켓 통신할 때와, 프로젝트의 기반 세트가 다를 때, 빈번히 변환을 해 주어야 한다.
사유 :: 다국어 작업(번역)을 하다보면, 멀티바이트에서 언어가 깨지는 문제가 발생한다. 이 때 유니코드로 변환해서 적용을 해준다면, 깨지는 문제는 해결된다.
#문자세트(Character Set)의 종류와 특성
. SBCS(Single Byte Character Set) :: 문자를 표현하는데 1Byte를 사용-ASCII
. MBCS(Multi Byte Character Set) :: 한글은 2Byte, 영문은 1Byte -MultiByte(다중바이트), 다중 은 꼴랑 1개이냐? 2개이냐?
. WBCS(Wide Byte Character Set) :: 모든 문자를 2Byte 사용 - Unicode ( 통일코드) .. 통일이 꼴랑 2로 했남?, Uni가 1개? Wide가 넓게... 이름 참 희안하게 .... ( 2^16 즉 65,536개....) Uni는 1개의 뜻이 아니라 Unique의 뜻....(고유의 코드값)
# 멀티바이트 문자 집합은 특정문자 집합마다의 코드 페이지가 존재한다.
예를 들어, 같은 코드 번호 일지라도 한글 코드페이지로 해석하면 한글이 나오지만, 일어코드 페이지로 해석하면 일어가 나온다.
MULTI-BYTE ( ISO-2200 :: 가변바이트)
(ANSI, UTF-8)
:: UTF-8 ( 1~4바이트) :: 1,112,064자 표현 가능
|
WIDE-CHAR 자료형... 유니코드 (Windows, Java에서는 UTF-16, 나머지 시스템에서는 UTF-8) |
비고 |
string | wstring | CA2W("멀티바이트를 유니코드로 변환") CW2A("유니코드를 멀티바이트로 변환") CW2A("유니코드를 UTF8로 변환", CP_UTF8) |
char * strlen() |
CString WCHAR wchar_t L"유니코드" lstrlenW() |
TCHAR는 char인지, wchar인지 구별하지 않고 코딩 컴파일러에서 기본을 설절함에 따라, 일괄 변경된다... |
LPCSTR | LPCWSTR | LP :: Long Pointer C : Const |
MultiByteToWideChar() | Windows OS에서만 가능 | |
WideCharToMultiByte()
|
Windows OS에서만 가능
|
|
CP_ACP :: 시스템에서 사용하는 MBCS(멀티바이트) -> UTF-16(유니코드) CP_UTF8->UTF-16(유니코드) |
||
MFC에서
유니코드->멀티바이트
char * ConvertUnicodeToMultiByte( CString strUnicode)
{
int nLen = WideCharToMultiByte( CP_ACP, 0, strUnicode, -1, NULL, 0, NULL, NULL); # 변환 대상에 대한 크기, 길이정보를 구한다. 변환 후의 크기.... widechar가 2바이트짜리, 3바이트짜리가 있으니....계산해서.. multibyte의 크기를 출력...
char* pMultiByte = new char(nLen);
memset( pMultiByte, 0x00, nLen * sizeof(char) );
WideChartoMultiByte( CP_ACP, 0, strUnicode, -1, pMultiByte, nLen, NULL, NULL); // {유니코드}->{멀티바이트}.[ASCII 또는 UTF-8], CP_ACP(아스키), CP_UTF8
retrun pMultiByte;
}
wchar_t strUnicode[256]={0,};
char strMultibyte[256]={0,};
wcscpy(strUnicode, 256, L"유니코드");
int len = WideCharToMultiByte( CP_ACP, 0, strUnicode, -1, NULL, 0, NULL, NULL);
WideCharToMultiByte(CP_ASCP, 0, strUnicode, -1, strMultibyte, len, NULL, NULL);
유니코드->UTF-8
wchar_t strUni[256]=L"유니코드";
char strUtf8[256]={0, };
int nLen = WideCharToMultiByte( CP_UTF8, 0, strUni, lstrlenW(strUni), NULL, 0, NULL, NULL);
WideCharToMultiByte( CP_UTF8, 0, strUni, lstrlenW(strUni), strUtf8, nLen, NULL, NULL);
멀티바이트->유니코드
CString ConvertMultibyteToUnicode(char *pMultibyte)
{
int nLen = strlen(pMultibyte);
WCHAR * *pWideChar = new WCHAR(nLen);
memset(pWideChar, 0x00, (nLen)*sizeof(WCHAR));
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)pMultiByte, -1, pWideChar, nLen);
CString strUnicode;
strUnicode.format(_T("%s"), pWideChar); // byte을 aligne해서 넣는다??
delete [] pWideChar;
return strUnicode;
}
wchar_t strUnicode[256]={0,};
char strMultibyte[256]={0,};
strcpy_s( strMultibyte, 235, "멀티바이트");
int nLen = MultiByteToWideChar( CP_ACP, 0, strMultibyte, strlen(strMultibyte), NULL, NULL);
MultiByteToWideChar(CP_ACP, 0, strMultibyte, strlen(strMultibyte), strUnicode, nLen);
UTF-8 -> 유니코드
wchar_t strUnicode[256]={0,};
char strUTF8[256]={0,};
strcpy_s( strUTF8, 256, "utf-8글자..");
int nLen = MultiByteToWideChar( CP_UTF8, 0, strUTF8, strlen(strUTF8), NULL, NULL);
MultiByteToWideChar( CP_UTF8, 0, strUTF8, strlen(strUTF8), strUnidcode, nLen);
#pragma once
#include <Windows.h>
#include <atlbase.h>
#include <iostream>
void func()
{
USES_CONVERSION; //매크로 선언
LPCSTR mChar;
LPCWSTR wChar = L"test";
mChar = W2A( wChar ); //유니코드 문자열을 멀티바이트문자열로 변환
wChar = A2W( mChar, CP_UTF8 ); //멀티바이트문자열을 유니코드문자열로 변환
}
인코딩(Encoding) - ASCII, ANSI, Multi-Byte, Unicode
아스키(ASCII)코드( 표)
:: 128개문자
ANSI
:: 영어만을 고려하여 만들어진 ASCII에서 다른 언어를 지원해야 할 필요가 생겨서...
:: 아스키의 확장판 : 앞의 7bit(ASCII와 동일) + 1 bit(CodePage) = 총 8bit로 사용
:::: CodePage = CP949, EUC-KR
한글처리
:: EUK-KR ( Extended Unix Code-Korea)
:::: 한글 지원을 위해 유닉스 계열에서 나온 '완성형' 코드 조합, ANSI를 한국에서 확장한 것으로 외국에서는 지원이 안 될 가능성이 높다.
:: CP949(Code Page 949)
:::: 한글 지원을 위해 윈도우즈 계열에서 나온 확장 완성형 코드
UTF-8
1. 유니코드를 위한 가변길이 문자 인코딩(멀티바이트)방식...
2. 처음 128글자는 ASCII코드값으로 동일
3. 2bytes를 사용하여, 중동지역 언어 또는 많은 유럽 언어를 표현...
4. 3byte를 사용하여 동아시아어권(한국,중국,일본..)
UTF-16
1. 한글의 경우, UTF-8로 저정할 경우, 3바이트를 필요로 하므로, UTF-16으로 저장하면 용량의 이점이 있음.
2. Endian 처리를 고려함에 따른 복잡성 증대나 ANSI와의 호환이 안되는 단점이 있음...
gcc 에서 characters
서버 프로그램에서 socker을 통해 전달받은 메시지 프로토콜은, 기본 인코딩은 유니코드임...(UString)...UTF-16 즉,, 2바이트 사용...
예시
//int n = ustrPassWord.Find( LPCWSTR(":MOD"));
int n = ustrPassWord.Find( LPCWSTR("\x00\x3A\x00\x4D\x00\x4F\x00\x44\x00"));
:: 유니코드에서 -> 멀티바이트로 변환
ustrAccountName.FromMBC( CP_UTF8, LPCSTR( g_theDoc.m_aryAuthAccountName.GetAt(i)) ); // MultiByte를 유니코드로 변환..)
:: 멀티바이트에서 -> 유니코드로 변환
mstrDebug.FromUnicode( CP_KOREAN, LPCWSTR(ustrUserID));
클라이언트에서 서버로 보낼 때 인코딩은?
:: 프로젝트 속성에서 _UNICODE가 선언되어 있음..
:: CString이 기본 자료형임..
:: MString으로 변환하여, 일반적인 char* 또는 숫자 기반을 처리함...
:: "~~~ :ENC"를 보내고 있음...
728x90
반응형
'프로그램언어 C C++' 카테고리의 다른 글
편미분 연쇄법칙 확장 (0) | 2023.05.23 |
---|---|
Dot Product of Matrix (0) | 2023.05.23 |
NumPy - 파이썬 라이브러리( C 코드, 수행속도, 다차원/배열 처리) (0) | 2023.04.16 |
[Selenium] WebDriver 사용-C# 샘플 프로그램 (0) | 2023.04.07 |
c# List Dictionary ContainsKey TryGetValue (0) | 2023.01.25 |