IT박스

Windows에서 MBCS와 UTF-8의 차이점

itboxs 2020. 12. 15. 08:28
반응형

Windows에서 MBCS와 UTF-8의 차이점


Windows의 문자 집합 및 인코딩에 대해 읽고 있습니다. Visual Studio 컴파일러 (C ++ 용)에 MBCS 및 UNICODE라는 두 개의 컴파일러 플래그가 있음을 알았습니다. 그들 사이의 차이점은 무엇입니까? 내가 얻지 못하는 것은 UTF-8이 MBCS 인코딩과 개념적으로 어떻게 다른가? 또한 MSDN 에서 다음 인용문을 찾았습니다 .

유니 코드는 16 비트 문자 인코딩입니다.

이것은 내가 유니 코드에 대해 읽은 모든 것을 부정합니다. 유니 코드는 UTF-8 및 UTF-16과 같은 다른 인코딩으로 인코딩 될 수 있다고 생각했습니다. 누군가이 혼란에 대해 좀 더 밝힐 수 있습니까?


Visual Studio 컴파일러 (C ++ 용)에 MBCS 및 UNICODE라는 두 개의 컴파일러 플래그가 있음을 알았습니다. 그들 사이의 차이점은 무엇입니까?

Windows API의 많은 함수는 두 가지 버전으로 제공됩니다. 하나는 char매개 변수 (로케일 특정 코드 페이지에서)를 사용하고 다른 하나는 wchar_t매개 변수 (UTF-16에서)를 사용합니다.

int MessageBoxA(HWND hWnd, const char* lpText, const char* lpCaption, unsigned int uType);
int MessageBoxW(HWND hWnd, const wchar_t* lpText, const wchar_t* lpCaption, unsigned int uType);

이러한 각 함수 쌍에는 UNICODE매크로 정의 여부에 따라 접미사가없는 매크로도 있습니다 .

#ifdef UNICODE
   #define MessageBox MessageBoxW
#else
   #define MessageBox MessageBoxA
#endif

이 작업을 수행하기 위해 TCHARAPI 함수에서 사용하는 문자 유형을 추상화 하도록 유형이 정의됩니다.

#ifdef UNICODE
    typedef wchar_t TCHAR;
#else
    typedef char TCHAR;
#endif

그러나 이것은 나쁜 생각 이었습니다. 항상 명시 적으로 문자 유형을 지정해야합니다.

내가 얻지 못하는 것은 UTF-8이 MBCS 인코딩과 개념적으로 어떻게 다른가?

MBCS는 "멀티 바이트 문자 집합"을 의미합니다. 문자 그대로의 경우 UTF-8이 자격이 될 것 같습니다.

그러나 Windows에서 "MBCS"는 "A"버전의 Windows API 함수와 함께 사용할 수있는 문자 인코딩만을 의미합니다. 여기에는 코드 페이지 932 (Shift_JIS), 936 (GBK), 949 (KS_C_5601-1987) 및 950 (Big5)이 포함되지만 UTF-8은 포함 되지 않습니다 .

UTF-8을 사용하려면를 사용하여 문자열을 UTF-16으로 변환 MultiByteToWideChar하고 함수의 "W"버전을 호출 WideCharToMultiByte한 다음 출력을 호출 해야합니다. 이것은 본질적으로 "A"함수가 실제로 수행하는 작업이므로 Windows가 UTF-8을 지원하지 않는 이유가 궁금 합니다.

가장 일반적인 문자 인코딩 을 지원할 수 없기 때문에 Windows API의 "A"버전은 쓸모가 없습니다. 따라서 항상 "W"기능을 사용해야합니다 .

유니 코드는 16 비트 문자 인코딩입니다.

이것은 내가 유니 코드에 대해 읽은 모든 것을 부정합니다.

MSDN이 잘못되었습니다. 유니 코드는 여러 인코딩이있는 21 비트 코딩 문자 집합으로, 가장 일반적인 것은 UTF-8, UTF-16 및 UTF-32입니다. (GB18030, UTF-7 및 UTF-EBCDIC과 같은 다른 유니 코드 인코딩도 있습니다.)

Microsoft에서 "유니 코드"를 언급 할 때마다 실제로는 UTF-16 (또는 UCS-2)을 의미합니다. 이것은 역사적인 이유 때문입니다. Windows NT는 유니 코드의 얼리 어답터였습니다. 16 비트가 모두에게 충분하다고 생각되었을 때, UTF-8은 플랜 9에서만 사용되었습니다. 따라서 UCS-2 유니 코드였습니다.


_MBCS 및 _UNICODE는 호출 할 TCHAR.H 루틴의 버전을 결정하는 매크로입니다. 예를 들어을 사용 _tcsclen하여 문자열 길이를 세는 경우 전처리 기는 _tcsclen_MBCS 및 _UNICODE라는 두 매크로에 따라 다른 버전으로 매핑 됩니다.

_UNICODE & _MBCS Not Defined: strlen  
_MBCS Defined: _mbslen  
_UNICODE Defined: wcslen  

이러한 문자열 길이 계산 함수의 차이점을 설명하려면 다음 예를 고려하십시오.
GBK (936 코드 페이지)를 사용하는 Windows 간체 중국어 버전을 실행하는 컴퓨터 상자가있는 경우 gbk 파일로 인코딩 된 소스 파일을 컴파일하여 실행합니다.

printf("%d\n", _mbslen((const unsigned char*)"I爱你M"));
printf("%d\n", strlen("I爱你M"));
printf("%d\n", wcslen((const wchar_t*)"I爱你M"));

결과는입니다 4 6 3.

다음은 I爱你MGBK 의 16 진수 표현입니다 .

GBK:             49 B0 AE C4 E3 4D 00                

_mbslen knows this string is encoded in GBK, so it could intepreter the string correctly and get the right result 4 words: 49 as I, B0 AE as , C4 E3 as , 4D as M.

strlen only knows 0x00, so it get 6.

wcslen consider this hexdeciaml array is encoded in UTF16LE, and it count two bytes as one word, so it get 3 words: 49 B0, AE C4, E3 4D.

as @xiaokaoy pointed out, the only valid terminator for wcslen is 00 00. Thus the result is not guranteed to be 3 if the following byte is not 00.


MBCS means Multi-Byte Character Set and describes any character set where a character is encoded into (possibly) more than 1 byte.

The ANSI / ASCII character sets are not multi-byte.

UTF-8, however, is a multi-byte encoding. It encodes any Unicode character as a sequence of 1, 2, 3, or 4 octets (bytes).

However, UTF-8 is only one out of several possible concrete encodings of the Unicode character set. Notably, UTF-16 is another, and happens to be the encoding used by Windows / .NET (IIRC). Here's the difference between UTF-8 and UTF-16:

  • UTF-8 encodes any Unicode character as a sequence of 1, 2, 3, or 4 bytes.

  • UTF-16 encodes most Unicode characters as 2 bytes, and some as 4 bytes.

It is therefore not correct that Unicode is a 16-bit character encoding. It's rather something like a 21-bit encoding (or even more these days), as it encompasses a character set with code points U+000000 up to U+10FFFF.


As a footnote to the other answers, MSDN has a document Generic-Text Mappings in TCHAR.H with handy tables summarizing how the preprocessor directives _UNICODE and _MBCS change the definition of different C/C++ types.

As to the phrasing "Unicode" and "Multi-Byte Character Set", people have already described what the effects are. I just want to emphasize that both of those are Microsoft-speak for some very specific things. (That is, they mean something less general and more particular-to-Windows than one might expect if coming from a non-Microsoft-specific understanding of text internationalization.) Those exact phrases show up and tend to get their own separate sections/subsections of microsoft technical documents, e.g. in Text and Strings in Visual C++

ReferenceURL : https://stackoverflow.com/questions/3298569/difference-between-mbcs-and-utf-8-on-windows

반응형