日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

C++字符串之一(字符表示)

發布時間:2023/12/20 c/c++ 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C++字符串之一(字符表示) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在C++中有兩種類型可以用于表示字符,char和wchar_t。

但是字符串格式的標準卻有很多種,如ASCII,UTF8,UTF16,UTF32等等。字符串的格式和char/wchar_t 的關系是什么呢?

首先要理解Unicode和UTF-8的關系,可以參考我轉帖的文章:http://www.cnblogs.com/whyandinside/archive/2012/02/05/2338841.html?

額外還有幾個問題需要解決:

1. UCS-2、UCS-4、BMP

UCS有兩種格式:UCS-2和UCS-4。顧名思義,UCS-2就是用兩個字節編碼,UCS-4就是用4個字節(實際上只用了31位,最高位必須為0)編碼。下面讓我們做一些簡單的數學游戲:

  UCS-2有2^16=65536個碼位,UCS-4有2^31=2147483648個碼位。

  UCS-4根據最高位為0的最高字節分成2^7=128個group。每個group再根據次高字節分為256個plane。每個plane根據第3個字節分為256行 (rows),每行包含256個cells。當然同一行的cells只是最后一個字節不同,其余都相同。

  group 0的plane 0被稱作Basic Multilingual Plane, 即BMP。或者說UCS-4中,高兩個字節為0的碼位被稱作BMP。

UCS-4的BMP去掉前面的兩個零字節就得到了UCS-2。在UCS-2的兩個字節前加上兩個零字節,就得到了UCS-4的BMP。而目前的UCS-4規范中還沒有任何字符被分配在BMP之外。

?

2. UTF-16是如何表示Unicode的?

在基本多語言平面內定義的符號((Basic Multilingual Plane, BMP),或稱第零平面(Plane 0)),使用2個字節表示,在此之外的字符(其他平面內的字符),則使用4個字節表示。由於第零平面內,從0XD800到0XDFFF之間的區段是沒有使用的,因此可以利用0XD800-0XDFFF之間的值來對輔助平面的字符進行編碼。?
其編碼方法是:

  • 如果字符編碼U小於0x10000,也就是十進制的0到65535之內,則直接使用兩字節表示;
  • 如果字符編碼U大於0x10000,由於UNICODE編碼範圍最大為0x10FFFF,從0x10000到0x10FFFF之間 共有0xFFFFF個編碼,也就是需要20個bit就可以標示這些編碼。用U'表示從0-0xFFFFF之間的值,將其前 10 bit作為高位和16 bit的數值0xD800進行 邏輯or 操作,將後10 bit作為低位和0xDC00做 邏輯or 操作,這樣組成的 4個byte就構成了U的編碼。
  • UTF-16可看成是UCS-2的父集。在沒有輔助平面字符Mapping of Unicode character planes(surrogate code points)前,UTF-16與UCS-2所指的是同一的意思。但當引入輔助平面字符後,就稱為UTF-16了。現在若有軟件聲稱自己支援UCS-2編碼,那其實是暗指它不能支援在UTF-16中超過2bytes的字集。對於小於0x10000的UCS碼,UTF-16編碼就等於UCS碼。

    ?

    3. wchar_t是UTF-16嗎?他們之間的關系是什么?

    wchar_t在不同的平臺上size是不一樣的,MSVC它是2字節的;而在Linux上它就是4字節了。wchar_t在Windows可用于存儲UTF-16的字符;而在Linux上往往用于存儲UTF-32在字符。

    比如:Windows上的函數MultiByteToWideChar是這樣描述的:Maps a character string to a UTF-16 (wide character) string. The character string is not necessarily from a multibyte character set.

    int MultiByteToWideChar( __in UINT CodePage, __in DWORD dwFlags, __in LPCSTR lpMultiByteStr, __in int cbMultiByte, __out LPWSTR lpWideCharStr, __in int cchWideChar );

    Different compilers and platforms define wchar_t differently, because they use different Unicode encoding techniques. On Windows/Visual C++ for instance, wchar_t is a 16 bit type, suitable for UTF-16. On GCC/Linux for instance, wchar_t is a 32 bit type, suitable for UTF-32.

    Depending on your requirements (speed, memory usage), you should pick an internal format that suits the platform. On Windows it might be UTF-16, and on Linux it might be UTF-32. That way you won't have to transcode strings all the time, just to make simple platform-defined operations on them (wcslen(), wcscmp(), etc).

    For external formats (text files, etc), I tend to use UTF-8. The reason is that files are considerably smaller if they contain text in a western language. Another benefit is that you don't have to consider endianess in UTF-8, which makes the chance of errors (on your or some other's part) less likely.

    4. SBCS、DBCS和MBCS?
    SBCS、DBCS和MBCS分別是單字節字符集、雙字節字符集和多字節字符集的縮寫。SBCS、DBCS和MBCS的最大編碼長度分別是1字節、兩字節和大于兩字節(例如4或5字節)。例如:代碼頁1252 (ANSI-拉丁文 I)是單字節字符集;代碼頁936 (ANSI/OEM-簡體中文 GBK)是雙字節字符集;代碼頁54936 (GB18030 簡體中文)是多字節字符集。單字節字符集中的字符都用一個字節表示。顯然,SBCS最多只能容納256個字符。

    雙字節字符集的字符用一個或兩個字節表示。那么我們從文本數據中讀到一個字節時,怎么判斷它是單字節字符,還是雙字節字符的首字符?答案是通過字節所處范圍來判斷。例如:在GBK編碼中,單字節字符的范圍是0x00-0x80,雙字節字符首字節的范圍是0x81到0xFE。我們順序讀取字節數據,如果讀到的字節在0x81到0xFE內,那么這個字節就是雙字節字符的首字節。GBK定義雙字節字符的尾字節范圍是0x40到0x7E和0x80到0xFE。

    GB18030是多字節字符集,它的字符可以用一個、兩個或四個字節表示。這時我們又如何判斷一個字節是屬于單字節字符,雙字節字符,還是四字節字符?GB18030與GBK是兼容的,它利用了GBK雙字節字符尾字節的未使用碼位。GB18030的四字節字符的第一字節的范圍也是0x81到0xFE,第二字節的范圍是0x30-0x39。通過第二字節所處范圍就可以區分雙字節字符和四字節字符。GB18030定義四字節字符的第三字節范圍是0x81到0xFE,第四字節范圍是0x30-0x39。

    ?

    5. UTF-8 可以和ANSII兼容;而UTF-16和UTF-32不可以。

    6. 字符串有兩種存儲方式:保存總長度和結束符。結束符是最常使用的,比如char字符串使用\0來判斷字符串結尾;而wchar的字符串使用’\0\0’來判斷字符串結尾。 保存總長度也是一種方式,在COM中BSTR就是這樣使用的。

    BSTR(Basic STRing)實際上是類Pascal字符串,在BSTR的前4個字節保存了字符串長度,所以BSTR內部可以包括\0,它也不是靠\0來判斷字符串結尾的。BSTR在c/c++中的定義實際上是wchar_t*,但因為BSTR是依靠前4個字節來判斷字符串長度的,所以它的分配和釋放都不同于普通的字符串,需要通過::SysAllocString和::SysFreeString等函數來分配和釋放。

    ?

    ?

    參考:

    1.?http://blog.sina.com.cn/s/blog_4c860d7e0100hzzj.html

    總結

    以上是生活随笔為你收集整理的C++字符串之一(字符表示)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。