詳細解說stl string
前言: string 的角色
1 string 使用
1.1 充分使用string 操作符
1.2 眼花繚亂的string find 函式
1.3 string insert, replace, erase 2 string 和 c風格字串
3 string 和 charactor traits
4 string 建議
5 小結
6 附錄前言: string 的角色
c++ 語言是個十分優秀的語言,但優秀並不表示完美。還是有許多人不願意使用c或者c++,為什麼?原因眾多,其中之一就是c/c++的文字處理
功能太麻煩,用起來很不方便。以前沒有接觸過其他語言時,每當別人這麼說,我總是不屑一顧,認為他們根本就沒有領會c++的精華,或者不
太懂c++,現在我接觸perl, php, 和shell指令碼以後,開始理解了以前為什麼有人說c++文字處理不方便了。
舉例來說,如果文字格式是:使用者名稱 **號碼,檔名name.txt
tom 23245332
jenny 22231231
heny 22183942
tom 23245332
...
現在我們需要對使用者名稱排序,且只輸出不同的姓名。
那麼在shell 程式設計中,可以這樣用:
awk '' name.txt | sort | uniq
簡單吧?
如果使用c/c++ 就麻煩了,他需要做以下工作:
先開啟檔案,檢測檔案是否開啟,如果失敗,則退出。
宣告乙個足夠大得二維字元陣列或者乙個字元指標陣列
讀入一行到字元空間
然後分析一行的結構,找到空格,存入字元陣列中。
關閉檔案
寫乙個排序函式,或者使用寫乙個比較函式,使用qsort排序
遍歷陣列,比較是否有相同的,如果有,則要刪除,copy...
輸出資訊
你可以用c++或者c語言去實現這個流程。如果乙個人的主要工作就是處理這種類似的文字(例如做apache的日誌統計和分析),你說他會喜歡
c/c++麼?
當然,有了stl,這些處理會得到很大的簡化。我們可以使用 fstream來代替麻煩的fopen fread fclose, 用vector 來代替陣列。最重要的是
用 string來代替char * 陣列,使用sort排序演算法來排序,用unique 函式來去重。聽起來好像很不錯 。看看下面**(例程1):
#include
#include
#include
#include
#include
using namespace std;
int main()
也還不錯吧,至少會比想象得要簡單得多!(**裡面沒有對錯誤進行處理,只是為了說明問題,不要效仿).
當然,在這個文字格式中,不用vector而使用map會更有擴充性,例如,還可通過人名找**號碼等等,但是使用了map就不那麼好用sort了。
你可以用map試一試。
這裡string的作用不只是可以儲存字串,還可以提供字串的比較,查詢等。在sort和unique函式中就預設使用了less 和equal_to函式, 上
面的一段**,其實使用了string的以下功能:
儲存功能,在getline() 函式中
查詢功能,在find() 函式中
子串功能,在substr() 函式中
string operator < , 預設在sort() 函式中呼叫
string operator == , 預設在unique() 函式中呼叫
總之,有了string 後,c++的字元文字處理功能總算得到了一定補充,加上配合stl其他容器使用,其在文字處理上的功能已經與perl, shell,
php的距離縮小很多了。 因此掌握string 會讓你的工作事半功倍。
1 string 使用
其實,string並不是乙個單獨的容器,只是basic_string 模板類的乙個typedef 而已,相對應的還有wstring, 你在string 標頭檔案中你會發現
下面的**:
extern "c++" // extern "c++"
由於只是解釋string的用法,如果沒有特殊的說明,本文並不區分string 和 basic_string的區別。
string 其實相當於乙個儲存字元的序列容器,因此除了有字串的一些常用操作以外,還有包含了所有的序列容器的操作。字串的常用操作
包括:增加、刪除、修改、查詢比較、鏈結、輸入、輸出等。詳細函式列表參看附錄。不要害怕這麼多函式,其實有許多是序列容器帶有的,
平時不一定用的上。
string 過載了許多操作符,包括 +, +=, <, =, , , <<, >>等,正式這些操作符,對字串操作非常方便。先看看下面這個例子:tt.cpp
(例程2)
#include
#include
using namespace std;
int main()
}看看如何呼叫:
#include
#include
using namespace std;
int main() char_traits不僅是在basic_string 中有用,在basic_istream 和 basic_ostream中也需要用到。
就像steve donovan在過度使用c++模板中提到的,這些確實有些過頭了,要不是系統自己定義了相關的一些屬性,而且用了個typedef,否則還
真不知道如何使用。
但複雜總有複雜道理。有了char_traits,你可以定義自己的字串型別。當然,有了char_traits < char > 和char_traits < wchar_t > 你
的需求使用已經足夠了,為了更好的理解string ,咱們來看看char_traits都有哪些要求。
如果你希望使用你自己定義的字元,你必須定義包含下列成員的結構: 表示式 描述
char_type 字元型別
int_type int 型別
pos_type 位置型別
off_type 表示位置之間距離的型別
state_type 表示狀態的型別
assign(c1,c2) 把字元c2賦值給c1
eq(c1,c2) 判斷c1,c2 是否相等
lt(c1,c2) 判斷c1是否小於c2
length(str) 判斷str的長度
compare(s1,s2,n) 比較s1和s2的前n個字元
copy(s1,s2, n) 把s2的前n個字元拷貝到s1中
move(s1,s2, n) 把s2中的前n個字元移動到s1中
assign(s,n,c) 把s中的前n個字元賦值為c
find(s,n,c) 在s的前n個字元內查詢c
eof() 返回end-of-file
to_int_type(c) 將c轉換成int_type
to_char_type(i) 將i轉換成char_type
not_eof(i) 判斷i是否為eof
eq_int_type(i1,i2) 判斷i1和i2是否相等
想看看實際的例子,你可以看看sgi stl的char_traits結構原始碼.
現在預設的string版本中,並不支援忽略大小寫的比較函式和查詢函式,如果你想練練手,你可以試試改寫乙個char_traits , 然後生成乙個
case_string類, 也可以在string 上做繼承,然後派生乙個新的類,例如:ext_string,提供一些常用的功能,例如:
4 string 建議
使用string 的方便性就不用再說了,這裡要重點強調的是string的安全性。
string並不是萬能的,如果你在乙個大工程中需要頻繁處理字串,而且有可能是多執行緒,那麼你一定要慎重(當然,在多執行緒下你使用任何
stl容器都要慎重)。
string的實現和效率並不一定是你想象的那樣,如果你對大量的字串操作,而且特別關心其效率,那麼你有兩個選擇,首先,你可以看看你
使用的stl版本中string實現的原始碼;另一選擇是你自己寫乙個只提供你需要的功能的類。
string的c_str()函式是用來得到c語言風格的字串,其返回的指標不能修改其空間。而且在下一次使用時重新呼叫獲得新的指標。
string的data()函式返回的字串指標不會以'/0'結束,千萬不可忽視。
盡量去使用操作符,這樣可以讓程式更加易懂(特別是那些指令碼程式設計師也可以看懂)
5 小結
難怪有人說:
string 使用方便功能強,我們一直用它!
STL string詳細用法
需要新增標頭檔案 string string和string.h是不一樣的標頭檔案 string str1 string str2 abcd 1 通過下標訪問 如果要讀入輸出整個字串只能用cin和cout 可以用c str將string型資料轉化成字元陣列輸出 string str abcd prin...
event詳細解說
event代表事件的狀態,例如觸發event物件的元素 滑鼠的位置及狀態 按下的鍵等等。event物件只在事件發生的過程中才有效。event的某些屬性只對特定的事件有意義。比如,fromelement 和 toelement 屬性只對 onmouseover 和 onmouseout 事件有意義。例...
詳細解說sizeof
50公尺的 http www.50mi.net開張了,所以50公尺邀請我給他寫點什麼。說實在的,作為乙個資深的潛水員,我還真沒動筆寫過什麼東西,所以絞盡腦汁也沒想起來能寫什麼的。不過鑑於50公尺喜歡在小孩子面前臭屁的,就寫一篇群裡討論很多的sizeof問題吧。1 什麼是sizeof 首先看一下siz...