电竞比分网-中国电竞赛事及体育赛事平台

分享

Delphi / C++ Builder 中字符串類型詳解

 quasiceo 2016-11-19

Delphi / C++ Builder 中字符串類型詳解

· C++ Builder、Delphi、雜談 · · ·瀏覽 1,210 次

字符串在編程中是一個(gè)常見的類型,但左一個(gè)類型,右一個(gè)類型可能把許多人都弄迷糊了。我寫這篇文章,試圖給大家理清 Delphi / C++ Builder 中的字符串類型。關(guān)于這些字符串類型的歷史,我們就不再啰嗦,歷史就是歷史,現(xiàn)在我們面對(duì)現(xiàn)實(shí)。

  • String 類型

String 類型在 Delphi / C++ Builder 不同的版本中,對(duì)應(yīng)于不同的類型,它們的分隔線是 Delphi / C++ Builder 2009。在 2009 以前,String 類型映射到了 AnsiString,而在 ≥ 2009 版本及以后,String 類型映射到了 UnicodeString。

  • ShortString 類型

ShortString 是 Delphi 中的一個(gè)短字符串類型,最大長度為 255 個(gè)字符。它的編碼方式和下面的 AnsiString 一致。

  • AnsiString 類型

AnsiString 類型是一種基于引用計(jì)數(shù)的字符串類型,它實(shí)際是代碼頁為 CP_ACP (0) 的字符串類型。在傳遞參數(shù)時(shí),直接增加的是字符串的引用計(jì)數(shù),而不是復(fù)制字符串的內(nèi)容,所以效率會(huì)比較高。英文數(shù)字和字符占用 1 個(gè)字節(jié),中文占用 2 或 4 個(gè)字節(jié),絕大部分中文占用的是 2 個(gè)字節(jié)。

  • Utf8String 類型

Utf8String 在 2009 以前的版本,被直接映射到了 AnsiString 上。而在 2009 及以后,Utf8String 是代碼頁為 CP_UTF8(65001)編碼的字符串類型。所以它也是一個(gè)基于引用計(jì)數(shù)的類型。英文數(shù)字和字符占用1個(gè)字節(jié),中文一般占用 2 到 4 個(gè)字節(jié),按 UTF8 規(guī)范最多占用 6 個(gè)字節(jié)。

  • WideString 類型

WideString 是 Unicode 16 LE 編碼的字符串,它是 COM 兼容的類型。當(dāng)它做為一個(gè)參數(shù)傳遞時(shí),它需要?jiǎng)?chuàng)建一份值拷貝,所以效率上要稍差。其中的每一個(gè)字符的類型都是 Delphi 中的 WideChar 或 C++ Builder 中的 wchar_t。對(duì)于 Unicode 16 LE 編碼字符,我們需要注意擴(kuò)展區(qū)字符,一個(gè)非擴(kuò)展區(qū)字符占用 2 個(gè)字節(jié),而擴(kuò)展區(qū)的字符占用 4 個(gè)字節(jié)。擴(kuò)展區(qū)字符的編碼首個(gè)字符的編碼范圍是 0xD800 ~ 0xDBFF,第二個(gè)字符的編碼范圍是 0xDC00 ~ 0xDFFF。

  • UnicodeString 類型

UnicodeString 是從 2009 開始引入的字符串類型,它也是基于引用計(jì)數(shù)的,所以效率上要比 WideString 快的多。我們可以認(rèn)為它是 WideString 的引用計(jì)數(shù)版本,對(duì)應(yīng)的也是Unicode 16 LE 編碼的字符串。而且 2009 開始將 String 類型映射到 UnicodeString。它的編碼方式和范圍同 WideStrnig。

  • RawString 類型

RawString 實(shí)際是一種新的字符串類型,它實(shí)際上是一種沒有任何內(nèi)部編碼的字符串類型。它只是一個(gè)容器,內(nèi)部的字符編碼沒有具體約定。

  • std::string

這個(gè)是 C++ 里的字符串類型,用于支持非 Unicode 16 LE 字符串,實(shí)際上是 basic_string<char>??梢哉J(rèn)為它是 Delphi 中 AnsiString 的 C++ 原生版本,不過要明白,它沒有引用計(jì)數(shù)。

  • std::wstring

這個(gè)是 C++ 里的字符串類型,用于支持 Unicode 16 LE 編碼字符串,實(shí)際上是 basic_string<wchar_t>。可以認(rèn)為它是 Delphi 中 WideString 的 C++ 原生版本。

  • PAnsiChar / char *

Ansi 編碼的字符串指針類型。AnsiString、Utf8String、std::string 的內(nèi)容都可以轉(zhuǎn)換成這種字符串指針類型。由于 ShortString 不是一種以 ASCII 碼 0 為結(jié)束的字符串,不符合 C 語言中的字符串規(guī)則,所以,一般情況下,我們需要先將 ShortString賦值給 AnsiString 然后才能轉(zhuǎn)換為這種指針類型。

  • PWideChar / wchar_t *

Unicode 編碼的字符串指針類型。WideString、UnicodeString、std::wstring 的內(nèi)容都可以轉(zhuǎn)換成這種字符串類型。

 

好了,前面說了那么多,那么這些字符串類型之間如何進(jìn)行相互轉(zhuǎn)換呢?

  • AnsiString   <-> Utf8String / WideString / UnicodeString 類型轉(zhuǎn)換

直接賦值即可,不需要額外的處理,也不會(huì)出現(xiàn)亂碼。反過來則由于可能字符集的支持問題,造成亂碼。

  • AnsiString -> PAnsiChar/char *

Delphi 中直接用 PAnsiChar(變量名) 即可,而 C++ 中使用 變量名.c_str() 函數(shù)來返回首個(gè)字符的地址。

  • WideString / UnicodeString -> PWideChar / wchar_t *

Delphi 中直接用 PWideChar(變量名)即可,而 C++ 中使用 變量名.c_str() 或 變量名.c_bstr() 函數(shù)來返回首個(gè)字符的地址。

  • ShortString -> PAnsiChar/char *

不好意思,此路不通。原因前面說了,所以賦值給一個(gè) AnsiString 然后再按前面的方法轉(zhuǎn)才是正道。

  • std::string -> char *

STL 的標(biāo)準(zhǔn)方法 變量名.begin() 就是了。

  • std::wstring -> wchar_t *

同上,STL里的 變量名.begin() 就是了。

反過來,我們將 PAnsiChar / char * 或 PWideChar / wchar_t * 類型賦值給其它類型時(shí),直接賦值就可以了。

在這里我還要提醒一點(diǎn),2009 以前版本的 Utf8String 實(shí)際上是 AnsiString 的別名,所以不要想當(dāng)然的認(rèn)為其中存貯的就是 UTF-8 編碼的字符串。

另外,在 FMX 環(huán)境下,AnsiString、WideString和Utf8String 這三個(gè)類型默認(rèn)都消失不見了,所以對(duì)應(yīng)的 PAnsiChar 也就沒有定義了。取而代之的是:MarshaledAString 等價(jià)于 PAnsiChar,而 MarshaledString 等價(jià)于 PWideChar,可以用在需要的場合。

如果有什么疑問或補(bǔ)充,我們回頭在群里聊。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多