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
이 작업을 수행하기 위해 TCHAR
API 함수에서 사용하는 문자 유형을 추상화 하도록 유형이 정의됩니다.
#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爱你M
GBK 의 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
'IT박스' 카테고리의 다른 글
Java 8에서 옵션 연결 (0) | 2020.12.15 |
---|---|
보수가 printf를 통해 다르게 작동하는 이유는 무엇입니까? (0) | 2020.12.15 |
절대 URL인지 상대 URL인지 확인 (0) | 2020.12.15 |
서명 계산을위한 HMAC-SHA256 알고리즘 (0) | 2020.12.15 |
yield를 사용한 재귀 (0) | 2020.12.15 |