字符与编码



                                                                            字符与编码

  • 字节与字符

    我们通常认为,字节(byte)和字符(character)是一致的,1个字节可以表示一个字符,一个字符占用1个字节,如:

           chars1[]="ABC";

           chars2[]="中文ABC";    

           //使用sizeof获取字符串长度

           printf("sizeofs1:%d\r\n",sizeof(s1));    //结果输出为:sizeof s1: 4

           printf("sizeofs2:%d\r\n",sizeof(s2));    //结果输出为:sizeof s1: 8

     

       可以看出,中文完全乱了。一个英文字符对应于一个字节,而一个中文字符则可能对应于两个字节。总之,字节与字符不是一一对应的,至于一个字符占用几个字节,则是由一张映射表来表示的,而这种映射表,就是编码表。

  • ANSIMBCS、与UNICODE

        目前计算机中用得最广泛的字符集及其编码,是由美国国家标准局(ANSI)制定的ASCIIAmerican StandardCode for Information Interchange,国家标准信息交换码)。ASCII码占用一个字节,准确地说,是7个比特。但汉字的数目很多,用简单的1个字节根本无法表达,因此决定采用2个字节来表示一个汉字。

        这样不同长度混排的编码方法,通常被叫做“MBCS(Muilti-BytesCharecter Set, 多字节字符集)”,如,“中文ABC”这串文本,它所占用的字节数可能就是:2×2+3=7

        为了使国际间信息交流更加方便,制定了UNICODE字符集,为各种语言中的每一个字符设定了统一并且唯一的数字编号,所有的字符都固定占用2个字节。如“中文ABC”,它所占用的字节数就是:5×2=10。使用UNICODE编码进行存放的字节也被称作宽字节字符。

        在标准C++中,可以这样定义一个MBCS或者ANSI的字符串,即: char s[]=“中文ABC”;

        定义一个UNICODE的字符串,可以使用L前缀,即:wchar_t s[]=L“中文ABC”;

  • TCHAR_T

        问题来了:我们是采用char还是wchar_t? 观察如下代码:

            char s[]=“中文ABC”;

        当我们准备采用wchar_t时,则需要改成:

           wchar_t s[]=L“中文ABC”;

       太麻烦了!!!因此开发者为此造出了一批宏,且看一段代码:

          TCHAR s[]=_T(“中文ABC);

       这段代码中,s到底是char数组还是wchar_t数组呢?Visual C++的解释是,如果需要它是char数组,那么它就是char数组;否则,它就是wchar_t数组。这样的魅力来源于宏TCHAR的定义:

    typedef unsigned char CHAR

    typedef unsigned wchar_t WCHAR

     

    #ifdef UNICODE

        typedefwchar_t TCHAR

    #else

           typedef unsigned char TCHAR

    #endif

        由此可以看出,CHAR实际就是unsigned charWCHARunsigned wchar_tTCHAR根据是否支持UNICODE而不同。

        同理,当UNICODE宏被定义,“_T(“中文ABC”)”会解释成“L(“中文ABC”)”,否则它只将其解释成“中文ABC””。

  • 字符串的长度

  1.  使用sizeof获取字符串长度

      sizeof用以获取字符数组的字节数(当然包括结束符0)。对于ANSI字符串和UNICODE字符串,形式如下:

          sizeof(cs)/sizeof(char)

          sizeof(ws)/sizeof(wchar_t)

    可以采用类似的方式,获取到其字符的数目。 

  2.  使用strlen()获取字符串长度

     strlen()wcslen()是标准C++定义的函数,它们分别获取ASCII字符串及宽字符串的长度,如:

          size_t strlen(const char *string);

          size_t wcslen(const wchar_t *string);

    strlen()wcslen()采取0作为字符串的结束符,并返回不包括0在内的字符数目。

  3. 使用CString::GetLength()获取字符串长度

           GetLength()返回字符而非字节的数目。比如:CStringW中,“中文ABC”的GetLength()会返回5,而非10。那么对于MBCS呢?同样,它也只能将一个字节当做一个字符,CStringA表示的“中文ABC”的GetLength()会返回7

  4. 使用std::string::size()获取字符串长度

       Length()size()的功能完全一样,他们仅仅返回字符而非字节的个数,如果遇到MCBS,它的表现和   CStringA::GetLength()一样。

  • 编写程序(各种获取字符串长度的方法)

    #include"stdio.h"

    #include"string"

    #include"afx.h"

    using namespacestd;

    void main()

    {

           char s1[]="中文ABC";

           wchar_t s2[]=L"中文ABC";

     

           //使用sizeof获取字符串长度

           printf("sizeofs1:%d\r\n",sizeof(s1));

           printf("sizeof s2:%d\r\n",sizeof(s2));

     

           //使用strlen获取字符串长度

           printf("strlens1:%d\r\n",strlen(s1));

           printf("wcslens2:%d\r\n",wcslen(s2));

     

           //使用CString::GetLength()获取字符串长度

           CStringA sa=s1;

           CStringW sw=s2;

           printf("sa.GetLength()s1:%d\r\n",sa.GetLength());

           printf("sw.GetLength()s2:%d\r\n",sw.GetLength());

     

           //使用string::size()获取字符串长度

           string ss1=s1;

           wstring ss2=s2;

           printf("ss1.size()s1:%d\r\n",ss1.size());

           printf("ss2.size()s2:%d\r\n",ss2.size());

          

    }

     

    输出结果为:

    sizeofs1:8

    sizeofs2:12

    strlen(s1):7

    wcslen(s2):5

    sa.GetLength():7

    sw.GetLength():5

    ss1.size():7

    ss2.size():5

猜你喜欢

转载自blog.csdn.net/u010901792/article/details/50411859