2020년 7월 1일 수요일

Multibyte. 그리고 Unicode 로의 변환

컴퓨터에서 글자는 그에 맞는 코드가 부여되어 있고 그 방식은 매우 많이 있다.

그 중 대표적인 것이 MBCS(MultiByte Code Set) 이고, 이를 대체한 것이 Unicode 이다.


MBCS 는 글자를 여러 char 을 이용해 나타낼 때 어떻게 기록할지에 대한 코드 셋이다.

c++ 에서 wchar_t 를 사용하지 않았을 적에 한국어를 표현할 수 있던 것은 이것 때문이다.


이 코드 셋은 윈도우의 언어설정, Locale 에 따라 바꿔 끼울 수 있다.

그래서 일본어로 설정된 컴퓨터가 저장한 Multibyte 데이터를 한국어 언어 설정인 컴퓨터로 읽으면 MBCS 가 달라서 글자가 깨진다.

단순히 현재 윈도우의 언어설정을 일본어로 바꾸면 문제는 사라진다.

하지만 매번 그럴 수 없고, 그렇기 때문에 우리는 Unicode 를 사용한다.


Unicode 는 단순히 문자와 숫자의 대응일 뿐이고, Encoding 방법은 또한 여러개 있다.

MBCS 역시 문자와 숫자의 대응인데, 이게 wchar_t 가 아니라 char 로 Encoding 될 때 주로 사용되기 때문에 이름이 마치 Encoding 방법처럼 보일 뿐이다.

 

그러면 Multibyte 를 Unicode 로 혹은 그 역으로 바꾸기 위해선 어떻게 해야하나?

다행히 이것을 해주는 함수를 MS 에서 제공해주고 있다.

우리가 준비할 것은 Multibyte 가 기록된 Code Set 과 변환할 데이터 뿐이다.


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
28
std::wstring ToWString(const std::string& string)
{
    wchar_t buffer[1024];    
 
    DWORD minSize = MultiByteToWideChar(CP_ACP, 0string.c_str(), -1NULL0);
 
    if (1024 < minSize)
 
        return L"OverFlowed";
 
    MultiByteToWideChar(CP_ACP, 0string.c_str(), -1, buffer, minSize);
 
    return std::wstring(buffer);
}
 
std::string ToString(const std::wstring& input)
{
    char buffer[1024];
 
    DWORD minSize = WideCharToMultiByte(CP_OEMCP, NULL, input.c_str(), -1NULL0NULL, FALSE);
 
    if (1024 < minSize)
        return "OverFlowed";
 
    WideCharToMultiByte(CP_OEMCP, NULL, input.c_str(), -1, buffer, 1024NULL, FALSE);
 
    return std::string(buffer);
}
cs

변환 방법은 위처럼 MultiByteToWideChar, WideCharToMultiByte 함수를 사용하면 된다.

먼저 크기를 받고 그 크기에 따라서 글자를 복사한다.


문제는 코드페이지이다. (위 함수 0번째 인자)


CP_ACP 가 한국어로 된 multibyte 도 잘 변환해주는데, 일본어는 안된다.


https://docs.microsoft.com/ko-kr/cpp/c-runtime-library/code-pages?view=msvc-160

그런데 위를 보면 코드페이지로 932 를 사용하라고 한다.

당혹스러운 것은 CP_ACP 가 정의된 파일에 932 로 된 enum value 는 없다는 것이다.

그냥 932 를 적어야 한다는 것.. ㄷㄷ


댓글 없음:

댓글 쓰기

List