代码之家  ›  专栏  ›  技术社区  ›  Naveen

Windows上MBCS与UTF-8的区别

  •  54
  • Naveen  · 技术社区  · 14 年前

    我正在读有关Windows上的字符集和编码。我注意到VisualStudio编译器(C++)中有两个编译器标志称为MBCS和Unicode。它们之间有什么区别?我不明白的是UTF-8在概念上与MBCS编码有何不同?另外,我发现以下引用 MSDN :

    4 回复  |  直到 14 年前
        1
  •  112
  •   Community CDub    8 年前

    Visual Studio编译器中的标志(用于 C++称为MBCS和Unicode。是什么 他们之间的区别?

    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

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

    然而,这一点, was a bad idea . 应该始终显式指定字符类型。

    我不明白的是UTF-8是怎样的 编码?

    MBCS代表“多字节字符集”。从字面上看,UTF-8似乎符合条件。

    但在Windows中,“MBCS”仅指可以与windowsapi函数的“A”版本一起使用的字符编码。这包括代码页932(Shift_JIS)、936(GBK)、949(KS_C_5601-1987)和950(Big5),但是 不是 UTF-8标准。

    MultiByteToWideChar ,调用函数的“W”版本,并调用 WideCharToMultiByte 在输出上。这就是“A”函数实际上所做的事情,这让我想知道 why Windows doesn't just support UTF-8

    无法支持 the most common character encoding 使Windows API的“A”版本毫无用处。因此,你应该

    Unicode是一种16位字符编码

    MSDN是错误的。Unicode是一种21位编码字符集,具有多种编码,最常见的是UTF-8、UTF-16和UTF-32(还有其他Unicode编码,如GB18030、UTF-7和UTF-EBCDIC。)

    每当微软提到“Unicode”时,他们实际上是指UTF-16(或UCS-2)。这是历史原因。windowsnt是Unicode的早期采用者,当时16位被认为对每个人都足够了,UTF-8只在计划9中使用。所以UCS-2

        2
  •  16
  •   Jichao    10 年前

    _tcsclen 为了计算字符串的长度,预处理器将映射 _tcsclen公司

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

    要解释这些字符串长度计数函数的区别,请考虑以下示例。

    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。

    GBK:             49 B0 AE C4 E3 4D 00                
    

    _mbslen知道这个字符串是用GBK编码的,所以它可以正确地解释这个字符串并得到正确的结果 4 话: 49 I , B0 AE 作为 爱 , C4 E3 作为 ä½ 4D 作为 M .

    0x00 ,所以它得到了 6 .

    wcslen认为这个hexdeciaml数组是用UTF16LE编码的,它将两个字节计为一个字,因此它得到 3 49 B0 , AE C4 , E3 4D .

    正如@xiaokaoy所指出的,对于 wcslen 00 00 . 因此,不能保证结果是正确的 如果以下字节不是 00 .

        3
  •  11
  •   stakx - no longer contributing Saravana Kumar    14 年前

    方法 Multi-Byte Character Set 和描述任何字符集,其中一个字符被编码成(可能)超过1字节。

    这个 / ASCII码 字符集不是多字节的。

    但是,它是一种多字节编码。它将任何Unicode字符编码为1、2、3或4个八位字节(字节)的序列。

    • UTF-8将任何Unicode字符编码为1、2、3或4字节的序列。

    • UTF-16将大多数Unicode字符编码为2字节,有些编码为4字节。

    U+000000 高达 U+10FFFF .

        4
  •  4
  •   Chris    10 年前

    Generic-Text Mappings in TCHAR.H 使用方便表总结预处理器指令-UnCudio和Y-MbC如何改变不同C/C++类型的定义。

    至于“Unicode”和“多字节字符集”,人们已经描述了它们的效果。我只想强调的是,这两个都是微软为一些非常具体的事情说话(也就是说,对于Windows来说,这些短语的含义没有人们想象的那么笼统,也比人们对文本国际化的理解更加具体。)这些确切的短语会显示出来,并倾向于在Microsoft技术文档中获得各自独立的节段/子节,例如 Text and Strings in Visual C++