1,本文分析 C++ 中的字符串,C 語言中的字符串利用的是 C 語言中的字符數組, 在 C 語言中沒有真正意義上的字符串,利用了字符數組表示了字符串,最初設 計 C 語言僅僅是為了開發 Unix 操作系統,而開發操作系統要處理的僅僅是數 據本身,關於字符串的處理很少,所以說當時沒有在 C 語言中內置一個字符串 現在絕大多數都是在用 C 語言開發應用程序,而開發應用程序中對字符串的處 理是非常多的,如果還是用字符數組表達字符串,一定會使得開發效率大大下 降,因此在 C++ 中有必要引入字符串的概念,不僅僅是用字符數組來模擬,而 是真正意義上的字符串;
2,歷史遺留問題:
1,C 語言不支持真正意義上的字符串;
1,C++ 也不支持;
2,C 語言用字符數組和一組函數實現字符串操作;
1,C++ 同樣支持;
3,C 語言不支持自定義類型,因此無法獲得字符串類型;
1,C++ 支持自定義類型,因此可以獲得字符串類型;
3,解決方案:
1,從 C 到 C++ 的進化過程引入了自定義類型;
2,在 C++ 中可以通過類完成字符串類型的定義;
4,C++ 中的原生類型系統是否包含字符串類型?
1,不包含;
5,標准庫中的字符串類:
1,C++ 語言直接支持 C 語言的所有概念;
2,C++ 語言中沒有原生的字符串類型;
3,C++ 標准庫提供了 string 類型:
1,string 直接支持字符串連接;
1,重載 “+”;
2,string 直接支持字符串的大小比較;
1,重載大小操作符,可以對字符串進行排序;
3,string 直接支持子串查找和提取;
4,string 直接支持字符串的插入和替換;
5,查閱 C++ 標准庫文檔;
6,字符串類的使用編程實驗:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 void string_sort(string a[], int len) 7 { 8 for(int i=0; i<len; i++) 9 { 10 for(int j=i; j<len; j++) 11 { 12 if( a[i] > a[j] ) // string 類重載了 “>”; 13 { 14 swap(a[i], a[j]); 15 } 16 } 17 } 18 } 19 20 string string_add(string a[], int len) 21 { 22 string ret = ""; 23 24 for(int i=0; i<len; i++) 25 { 26 ret += a[i] + "; "; // string 類重載了 “+=” 和 “+”; 27 } 28 29 return ret; 30 } 31 32 int main() 33 { 34 string sa[7] = 35 { 36 "Hello World", 37 "D.T.Software", 38 "C#", 39 "Java", 40 "C++", 41 "Python", 42 "TypeScript" 43 }; 44 45 string_sort(sa, 7); 46 47 for(int i=0; i<7; i++) 48 { 49 cout << sa[i] << endl; 50 } 51 52 cout << endl; 53 54 cout << string_add(sa, 7) << endl; 55 56 return 0; 57 }
2,輸出結果:
1 C# 2 C++ 3 D.T.Software 4 Hello World 5 Java 6 Python 7 TypeScript 8 9 C#; C++; D.T.Software; Hello World; Java; Python; TypeScript;
3,C++ 中沒有必要使用字符數組模擬字符串了,直接使用標准庫中的 string 類型;
7,標准庫中的字符串類:
1,字符串與數字的轉換:
1,標准庫中提供了相關的類對字符串和數字進行轉換;
1,基於字符串流類 sstream 來進行轉換;
2,sstream 類誕生的目的就是為了支持字符串和數字之間的相互轉換;
2,字符串流類(sstream)用於 string 的轉換:
1,<sstream> - 相關頭文件;
2,istringstream - 字符串輸入流;
3,ostringstream - 字符串輸出流;
2,使用方法:
1,string ==> 數字;
1,istringstream iss("123.45");
2,double num;
3,iss >> num;
1,傳輸成功,表達式值為 true,失敗則為 false;
4,上述三步,等價於 istringstream("123.45") >> num;
2,數字 ==> string:
1,ostringstream oss;
2,oss << 543.21;
1,返回值是 oss 本身;
3,string s = oss.str();
4,上述三步,等價於 s =(sotringstream() << 543.21).str();
3,輸入輸出是相對內存而言的;
8,字符串和數字的轉換編程實驗:
1,main.cpp 文件:
1 #include <iostream> 2 #include <sstream> 3 #include <string> 4 5 using namespace std; 6 7 /* 實際工程用法,目前為止(后續采用模板),只能通過 C 語言中的宏來只寫一遍代碼處理所有的因類型不同而要完成的函數重載 */ 8 #define TO_NUMBER(s, n) (istringstream(s) >> n) // 宏要在一行代碼中完成,直接調用構造函數產生臨時對象,臨時對象聲明周期可以滿足要求;這里定義了臨時對象,並將臨時對象傳遞到 n 中去; 9 #define TO_STRING(n) (((ostringstream&)(ostringstream() << n)).str()) // 調用構造函數生成臨時對象,這里 (ostringstream&) 為強制類型轉換否則編譯器顯示 error: ‘struct std::basic_ostream<char, std::char_traits<char> >’ has no member named ‘str’這個錯誤; 10 11 int main() 12 { 13 double n = 0; 14 15 if( TO_NUMBER("234.567", n) ) // 返回 bool 類型的變量; 16 { 17 cout << n << endl; 18 } 19 20 string s = TO_STRING(12345); 21 22 cout << s << endl; 23 24 return 0; 25 }
9,面試題分析:
1,示例:abcdefg 循環右移 3 位后得到 efgabcd;
10,用 C++ 完成面試題編程實驗:
1,main.cpp 文件:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 /* 將 string rignt_func(const string& s, unsigned int n) 直接更改名字變成右移操作符重載 */ 7 string operator >> (const string& s, unsigned int n) 8 { 9 string ret = ""; 10 unsigned int pos = 0; // 找子串右移開始的位置; 11 12 n = n % s.length(); // 防止右移位置很大的情況,讓其合法; 13 pos = s.length() - n; // 得到最終想要的位置; 14 ret = s.substr(pos); // 從 pos 開始直到末尾提取子串; 15 ret += s.substr(0, pos); //原來的字符串並沒有被破壞,提取到 pos 之前的字符; 16 17 return ret; 18 } 19 20 int main() 21 { 22 string s = "abcdefg"; 23 string r = (s >> 3); 24 25 cout << r << endl; 26 27 return 0; 28 }
2,輸出結果:
efgabcd
3,整個過程沒有出現字符數組,我們站在了更高的角度處理問題,並且函數內部實現也非常簡單,沒有 for 循環;
4,面試時,對於一個面試題,面試官一般不需要最后的答案,需要的是你如何思考,如何解決的,考察是思維能力和解決問題能力;
11,小結:
1,應用開發中大多數的情況都在進行字符串處理;
2,C++ 中沒有直接支持原生的字符串類型;
3,標准庫中通過 string 類支持字符串的概念;
4,string 類支持字符串和數字的相互轉換;
5,string 類的應用使得問題的求解變得簡單;
