1 / 46

物件導向的字串處理

22. 物件導向的字串處理. 內建的完整 類別 string 具有 豐富的成員函數,能以物件導向的語法處理字串,讓程式設計者免除空間安排及安插結尾符號等瑣碎的工作。. Chap 22 物件導向的字串處理. 22.1 C 風格的字串和物件導向的 string 類別 22.2 String 物件的定義 22.3  字串的更改、清除、剪接與部份複製 22.4  字串之間的比對和比較 22.5  字串物件與 C-style 字串的互換. 22.1 C 風格的字串和物件導向的 string 類別. C-style string (C 風格的字串 )

kalei
Download Presentation

物件導向的字串處理

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 22 物件導向的字串處理 • 內建的完整類別string具有豐富的成員函數,能以物件導向的語法處理字串,讓程式設計者免除空間安排及安插結尾符號等瑣碎的工作。

  2. Chap 22物件導向的字串處理 • 22.1C風格的字串和物件導向的string類別 • 22.2String物件的定義 • 22.3 字串的更改、清除、剪接與部份複製 • 22.4 字串之間的比對和比較 • 22.5 字串物件與C-style字串的互換

  3. 22.1 C風格的字串和物件導向的string 類別 • C-style string (C風格的字串) 由資料型態為char構成的一維陣列,結尾處加上 ‘\0’ 做為字串的結束符號。 • 宣告C風格字串的三種方式 char s1[20] = "Hello, 您好!"; // 陣列式的宣告 char* ps2 = "Hello, 您好!"; // 指標式的宣告 char s3[10] = {'G', 'o', '!', '\0'}; // 列舉陣列元素式的宣告

  4. 使用自動設定字元陣列長度的語法宣告C風格的字串使用自動設定字元陣列長度的語法宣告C風格的字串 // 自動設定字元陣列的長度 char s4[] = "Hello, 您好!"; char s5[] = {'\n', 'G', 'o', '!' , '\0'};

  5. 物件導向的string類別 • 在STL (the Standard Template Library) 中定義。使用前要在程式開頭處加上 #include <string> 以含入標頭檔 <string>,完成string類別的宣告。 • 可以動態地配置記憶空間。 • 有完整的成員函數,提供了許多方便的運算子。

  6. 22.2 定義String物件 (1/2) string S1; // 定義一個空的string物件S1 string S2, S3, S4; // 同時定義三個空的string物件 string S5("A 是 123"); // S5的容是 "A是123" string S51 = "A 是 123"; // S51的容是 "A是123" string S6(S5) ; // 複製S5的內容,另造一個新物件S6

  7. string S61 = S5; // 複製S5的內容,另造一個新物件S61 string S7(s); // S4的內容由C-style字串s構成

  8. 定義String物件 (1/2) string S5("A 是 123"); // S5的內容是 "A是123“ string S8(5, ‘c’); // S8由5個 ‘c’ 字元所構成 string S9(S5, 2); // S9由S5[2]及其後的所有字元 //構成,亦即 "是123"; string S91 (S5, 2, 4); // S91由S5[2]起算,長度為4個字元的 // 部份所構成,亦即 "是1“ string* pS = new string[2]; //動態配置了兩個string物件, // pS指向第一個物件的起頭處

  9. 使用下標指定string物件的元素 • S1[0]代表string物件S1的第一個字元。 • S1[1]代表string物件S1的第二個字元。

  10. 22.3 字串的更改、清除、剪接與部份複製 (1/5) • (假設S1和S2為兩個先前已定義過的字串物件): S1[2]='G'; // 將S1的第3個字元改成 'G' S1.at(2)=‘G’; // 與S1[2]=‘G’;相同 S2.insert(2,S1);//在S2[2]前插入字串 S1

  11. 字串的更改、清除、剪接與部份複製 (2/5) swap(S1,S2); // 將 S1 和 S2 的內容互相交換 S1.swap(S2); // 將 S1 和 S2 的內容互相交換 S1.resize(3); // 只保留 S1[0] 到 S1[2] 共3個字元, // 其餘字元全數清除 S1.resize(5,‘A’); // 如果 S1 原來的字串長度大於 5, // 只保留前 5 個字元,如果原來的字串長度 // 小於 5,則不足之處全補上字元 'A'

  12. 字串的更改、清除、剪接與部份複製 (3/5) S2.erase(2); // 清除自S2[2] 起之後的所有字元 S2.erase(2,3); // 清除從S2[2] 起共3個字元 S2.erase(); // 將S2 的內容全部清除 S2.erase(2,5); // 將 S2[2] 到 S2[6]共5個字元清除 S2.replace(2,3,S1); // 將 S2[2] 到 S2[4] 共3個 //字元清除並以 S1 取代

  13. 字串的更改、清除、剪接與部份複製 (4/5) S2=S1; // S2 的內容與 S1相同,但兩者為獨立物件 S2.assign(S1); // 與 S2=S1 相同 S2.assign(S1,2,3); // S2的內容為 S1[2]到 S1[4]共3個字元 S2=S1.substr(2); // 將S1[2]及其後的所有內容存到 S2 中 S2=S1.substr(2,3); // 將 S1[2] 到 S1[4] 共3個字元存到 // S2 中,與 S2.assign(S1,2,3) 相同

  14. 字串的更改、清除、剪接與部份複製 (5/5) S2.append(S1); // 在 S2 之後串接上 S1 S2.append(S1,2,3); // 在 S2 之後串接上 S1[2] 到 S2[4] // 共3個字元 S3=S1+S2; // S3 的內容改為由 S1 和 S2 串接而成 S2+=S1; // 在 S2 之後串接上 S1

  15. 使用begin() 和end() 兩個指標物件直接指定string物件的起頭和結尾處 // 將 S2[2] 到 S2 倒數第4個字元間的內容附加到 S1 之後: S1.append(S2.begin()+2, S2.end()-3); // 將 S2[2] 到 S2 倒數第4個字元間的內容清除:S1.erase(S1.begin()+2, S1.end()-3); // 將 S1 的前3個字元複製到 S2[2] 至 S2[4] 的位置:S1.copy(S2.begin()+2, 3);

  16. 範例程式 (字串物件的操作) 檔案ModifyString.cpp // ModifyString.cpp #include <string> #include <iostream> using namespace std; int main() { string S1("0123456789"), S2("abcdefghi"); string S3("必需 do it"), S4, S5 ("長度是 123"); string S6(1,'A'), S7(S3,1,3), S8 (S3, 2, 5); cout << "(1) S3 原來的內容是: " << endl; cout << " " << S3 << endl; cout << " 執行 string S8 (S3, 2, 5); 後\n" << " S8 = " << S8 << endl; cout << "(2) S1 原來的內容是: " << endl; cout << " " << S1 << endl; S1.resize(7); cout << " 執行 S1.resize(7); 後\n " << " S1 = " << S1 << endl; cout << "(3) S5 原來的內容是: " << endl; cout << " " << S5 << endl; S5='A';

  17. cout << " 執行 S5 ='A'; 後\n " << " S5 = " << S5 << endl; cout << "(4) S1 原來的內容是:" << endl; cout << " " << S1 << endl; cout << " S3 原來的內容是:" << endl; cout << " " << S3 << endl; S3.copy(S1.begin()+2,4); cout << " 執行 S3.copy(S1.begin()+2,4) 後." << endl; cout << " S1 的內容是:" << endl; cout << " " << S1 << endl; cout << " S3 的內容是:" << endl; cout << " " << S3 << endl; cout << "(5) S1 原來的內容是:" << endl; cout << " " << S1 << endl; cout << " S3 原來的內容是:" << endl; cout << " " << S3 << endl;

  18. S3=S1.substr(2,5); cout << " 執行 S3=S1.substr(2,5); 後." << endl; cout << " S3 的內容是:" << endl; cout << " " << S3 << endl; cout << "(6) S1 原來的內容是:" << endl; cout << " " << S1 << endl; S1.erase(1,3); cout << " 執行 S1.erase(1,3); 後." << endl; cout << " S1 的內容是:" << endl; cout << " " << S1 << endl; cout << "(7) 執行 S4=S1+S3; 後." << endl; S4=S1+S3; cout << " S4 的內容是:" << endl; cout << " " << S4 << endl; return 0; };

  19. 程式執行結果 (1) S3 原來的內容是: 必需 do it 執行stringS8 (S3, 2, 5); 後 S8 = 需 do (2) S1 原來的內容是: 0123456789 執行 S1.resize(7); 後 S1 = 0123456 (3) S5 原來的內容是: 長度是 123 執行 S5 ='A'; 後 S5 = A

  20. (4) S1 原來的內容是: 0123456 S3 原來的內容是: 必需 do it 執行 S3.copy(S1.begin()+2,4) 後. S1 的內容是: 01必需6 S3 的內容是: 必需 do it (5) S1 原來的內容是: 01必需6 S3 原來的內容是: 必需 do it 執行 S3=S1.substr(2,5); 後. S3 的內容是: 必需6

  21. (6) S1 原來的內容是: 01必需6 執行 S1.erase(1,3); 後. S1 的內容是: 0需6 (7) 執行 S4=S1+S3; 後. S4 的內容是: 0需6必需6

  22. 22.4 字串之間的比對和比較 (1/2) S1.find(S2); // 在S1中尋找S2的組成字元所在的位置 S1.find(S2,S3); // 由 S1[3]開始尋找 // S2 的組成字元所在的位置 S1.find_first_of(S2); // 在 S1 中尋找第一個吻合// S2 的組成字元所在的位置 S1.find_first_of(S2,3); // 由 S1[3] 開始尋找第一個吻合// S2 的組成字元所在的位置

  23. 字串之間的比對和比較 (2/2) //在 S1 中尋找第一個不吻合 S2 的組成字元所在的位置 S1.find_first_not_of(S2); // 在 S1 中尋找最後吻合S2 的組成字元所在的位置 S1.find_last_of(S2); // 在 S1 中尋找最後不吻合 S2 的組成字元所在的位置; S1.find_last_not_of(S2);

  24. 字串內容的檢查 S1.size(); // 檢查 S1 內的字元數目 S1.length(); // 與 S1.size(); 相同 S1.empty(); // 檢查 S1是否為空字串,輸出為 // true 或 false

  25. 範例程式 檔案 FindSub.cpp • 使用find() 在字串物件 (S1和S2) 中尋找吻合另一個字串物件 (Sub1和Sub2) 的位置。 // FindSub.cpp #include <string> #include <iostream> using namespace std; int main() { string S1="I do not know it at all."; string S2="說真的,我不知道她是否愛我。"; int Site, Length1, Length2, Count; string Sub1 = "no"; string Sub2 = "我"; Length1 = Sub1.size(); Count = 0; Site = 0; cout << "字串 \"" << Sub1 << "\" 位於字串 \"" << S1 << "\" 的位置在:" << endl;

  26. while ((Site = S1.find(Sub1,Site)) !=-1) { cout << Site << " "; Site=Site+Length1; Count++; }; cout << "\n共有 " << Count << " 個 \"" << Sub1 << "\" 在其中." << endl; Length2 = Sub2.size(); Count = 0; Site = 0; cout << "中文字 \"" << Sub2 << "\" 位於字串 \"" << S2 << "\" 的位置在:" << endl; while ((Site = S2.find(Sub2,Site)) !=-1) { cout << Site << " "; Site=Site+Length2; Count++; }; cout << "\n共有 " << Count << " 個 \"" << Sub2 << "\" 在其中." << endl; return 0; }

  27. 程式執行結果 (1) 字串 “no" 位於字串 "I do not know it at all." 的位置在: 5 10 共有 2 個 "no" 在其中. (2) 中文字 "我" 位於字串 "說真的,我不知道她是否愛我。" 的位置在: 8 24 共有 2 個 "我" 在其中

  28. 字串之間的比較 • 字串由char構成,依照ASSII碼的編號方式可以比較大小。 • 字串有兩種比較方式: (1)使用重載運算子, (2)使用成員函數 compare()

  29. 使用重載運算子比較字串 S1 = S2+S3; // 將 S2 和 S3 串接合併,存入 S1 S1 += S2; // S1 的尾端串接了 S2 的內容 cout << S1; // 將 S1 透過資料流輸出 cin >> S2; // 透過資料流將資料輸入 S2 內其中 //cin >> S2; 可以寫成 //getline(cin,S2);

  30. 使用成員函數Compare() • 指令 S1.compare(S2); 的輸出值有 1、0和 -1三種: 1 如果 S1 > S2 0 如果 S1 = S2 -1 如果 S1 < S2

  31. 範例程式 檔案 StringBubble.cpp • 改寫10.6節的範例程式Bubble.cpp,使用比較大小的運算子「>」將字串依照字典的次序排列。 還運用了22.3節介紹的字串成員函數swap() 代替原來自行定義的樣版函數Exchange() 以互相交換字串的內容。

  32. // StringBubble.cpp #include <string> #include <iostream> using namespace std; // --- 定義樣版函數 Bubble() ------------------- template <class T> void Bubble(T * const V, int N ) { for (int i=0; i<N; i++) for (int j=N-1; j>i; j--) if (V[j]<V[j-1]) swap(V[j],V[j-1]); return; }

  33. // ---- 主程式 --------------------------------- int main() { const int Size = 5; int i; string Students[Size]= {"Nancy","Lulu", "Margaret","Stephanie","Monica"}; cout << "\n執行 Bubble() 之前, Data 的值是:" << endl; for (i=0; i<Size; i++) cout << "(" << i+1 << ") " << Students[i] << endl; Bubble(Students, Size); cout << "\n執行 Bubble() 之後, Data 的值是:" << endl; for (int i=0; i<Size; i++) cout << "(" << i+1 << ") " << Students[i] << endl; return 0; }

  34. 程式執行結果 執行 Bubble() 之前,Data 的值是: (1) Nancy (2) Lulu (3) Margaret (4) Stephanie (5) Monica 執行 Bubble() 之後,Data 的值是: (1) Lulu (2) Margaret (3) Monica (4) Nancy (5) Stephanie

  35. 使用C_str() 成員函數將字串物件轉換為C-style字串 • 使用資料型態為「const char *」的指標pSc,以代表 C-style 字串: string S1("FileName"); const char* pSc; pSc = S1.c_str(); • 這時pSc只是指向原先S1物件內字元陣列的指標,並沒有另外複製產生新的字串。

  36. c_str() 的轉換結果屬於資料型態「const char *」 • S1.c_str()無法直接由「char *」的指標接收: char* pS2; // pS2 為 「char *」的指標 pS2 = S1.c_str(); // 錯誤!

  37. 將字串物件的內容複製到字元陣列char [] string S1("FileName"); char CS[10]; strcpy(CS, S1.c_str());

  38. 使用strcpy() 將S1的內容複製到字元陣列指標「char *」 • 指標所代表的位置必需有夠的空間: stringS1("FileName"); char* pS = new char[S1.length()+1]; strcpy(pS, S1.c_str());

  39. 使用data() 成員函數將字串物件轉換為C-style字串 stringS2("abcdefghi"); const char* pSc; pSc = S2.data(); • 這個語法並沒有另外複製產生新的字串。

  40. 將C-style字串轉換為string物件 string S3, S4; char CS2[20] = "Hello! 您好!"; char* pS2 = "早安!"; S3 = CS2; // 「=」在string類別中已正確重載過 S4 = pS2; • 此時S3和S4為複製產生的新字串物件。

  41. 範例程式 檔案 CString.cpp • 示範和驗證字串物件和C-style string之間的轉換。

  42. 程式執行結果

More Related