首頁 / 5.1字串的表示

5.1字串的表示

本節是給C語言初學者字串概念的快覽摘要,說明在C裡頭字元字串如何表示以及一些常見陷阱,假如你已經熟悉這個部份,你可以跳過這一節。

字串 是字元物件的陣列,但是字串值變數通常宣告為char *形式的指標,這樣的變數不能增加字串文字的空間;以致它們必須儲存在某個地方—在陣列變數、字串常數或是動態配置的記憶體中(見記憶體配置),由你決定儲存選擇記憶體空間位址給指標變數。你也可以儲存一個null指標在指標變數中,null指標不指向任何地方,所以嘗試參考它指向的字串會產生錯誤。

“字串”通常指的是多位元組字元字串而不是寬字元字串,寬字元字串是型態wchar_t的陣列而多位元組字元字串通常使用型態wchar_t *的指標。

按照慣例,null 字元、'\0',做為多位元組字元字串的結束,而null寬字元 L'\0',則做為寬字元字串的結束,例如,測試看看char * 變數 p 指向一個null字元做為字串的結束,你可以寫 !*p 或 *p == '\0'。

一個空字元跟空指標在概念上是完全不同的,儘管這兩個都是用整數0來表示。

字串實字(String literals)在C程式的原始碼中以雙引號字元間的字元字串來表示以及初始雙引號字元前加大寫‘L’ (ell)字元(如L"foo"),在ISO C中,字串實字也可以用字串串接t"a" "b" 或"ab"來形成,對寬字元字串來說,可以用L"a" L"b" 或 L"a" "b",字串實字的修改在GNU C編譯器裡是不允許的,因為實字被放在唯讀記憶體中。

字元陣列被宣告為const也不能修改,宣告不可修改的字串字標為型態const char *通常是比較好的風格,因為這可以允許C編譯器偵測意外的修改以及提供一些關於你的程式打算處理字串的文件。

字元陣列記憶體配置的數量可以通過標示字串結束的空字元來擴展,在這份文件裡,術語allocated size 用來說明字串記憶體配置的數量,而術語length說明字元數(但不包括)終止的空字元,糟糕的程式錯誤會試著放更多的字元在字串裡而不是以符合其配置的數量來使用,當要撰寫增加字串或是移動字元進入已配置的陣列的程式碼時,你應該很小心地追蹤文字的長度以及對溢出陣列作明確的檢查,很多函式庫的函式不會為你這件事!也要記得你需要多配置一個位元來持有標記字串結束的空字元。

本來字串是每各位元表示一個單一字元的位元組序列,假如字串使用單位元字元編碼的話直到今天仍然是正確的,但是假如字串使用多位元編碼的話事情就不一樣了(編碼的更多資訊見擴充的字元簡介),這兩種字串的程式設計介面沒有不同;程式設計師必須瞭解這一點並依此解譯位元序列。

但因為沒有分開介面來留意這些差異導致這些以位元為基礎的字串函式有時候很難用,因為這些函式的計數參數會指定位元來呼叫strncpy造成會將多位元字元切成一半,並放置一個未完成(因此不能用)的位元序列在目標緩衝區裡。

要避免這些問題新版的ISO C標準介紹了第二組處理寬字元 (見擴充的字元簡介)的函式,這些函式沒有單一位元版本的問題因為每個寬字元都是合法可解譯的值,這不代表在任意點切割寬字元字串是沒有問題的,它通常是給以字母為基礎的語言使用(除了非正規化的文字)而以音節為基礎的語言則仍然有一個寬字元需要完成一個邏輯單元的問題,這是一個C函式庫函式未被設計來解決較高層次的問題,但至少好到可以不會產生錯的位元序列,而且較高階的函式在寬字元上比多位元字元上更易操作所以一般的建議是在內部使用寬字元而不用管文字是否只是簡單的複製。

本章的其餘部份會同時討論寬字元字串跟多位元字元字串函式的處理因為幾乎都有等效的方法可以使用。

下一節:字串和陣列規範,這一章:字串和陣列的工具

發表迴響

你的電子郵件位址並不會被公開。 Required fields are marked *

*

這個網站採用 Akismet 服務減少垃圾留言。進一步瞭解 Akismet 如何處理網站訪客的留言資料

Scroll To Top