相信學習過計算機編程的人,基本應該都接觸過C語言,在C語言中處理字符串大家一定多遇到過,
也都知道處理字符串非常麻煩,而在C++裡面,由標准庫string類提供對可變長的字符串的支持。下面
來看看string類的特性。
1、使用的先決條件
在使用標准庫之前必須包含相應的頭文件, 要使用string類型,就需要包含相應的頭文件,如下所示:
#include <string>
在使用iostream的時候,我們未來引用iostream裡面的類,前面需要加上 std:: 來表示引用的是標准
IO庫提供的功能,同樣在使用string類的時候,需要加上一個表示作用域的限制修飾的說明,如下所示:
std::string str; //定義一個string的對象str
在每一次定義的時候都要這樣使用 std:: 很麻煩,C++提供了一種更方便的機制,如下:
using std::string;
在源文件裡面加上上面這一句, 在使用的時候,就可以直接使用 string來定義對象,如下所示:
string str;
2、string類的初始化
string類提供了多種初始化方法:
1) string str; //初始化為空字符串, 調用默認構造函數,
2) string str2="volcanol"; // 賦值初始化,復制str2為"volcanol"的一個副本,
3) string str1("volcanol"); //直接初始化,調用初始化函,
4) string str1="volcanol"
string str2(str1); //利用 string對象初始化string str對象
5) string str1(3,'c'); //初始化str1為"ccc",
3、string對象的讀寫
可以利用iostream提供的輸入和輸出機制來對string對象進行操作。
輸入:
string str; cin>>str;
這樣就可以通過標准輸入來輸入字符到string對象中, 要注意的是:
A) cin在輸入的的時候會忽略開始的空白符(空格,制表符,換行符),然後從非空白字符開始讀入
B) cin在輸入的時候,會在再次遇到空白字符後結束輸入。
這裡的意思就是: 通過 cin>>str讀入的字符流不會包含 endl 換行符,因此如果要換行的話,就
需要自己添加換行符。
同樣可以利用cout<<來輸出string對象,如下所示:
cout<<str<<endl;
下面是一段例子代碼:
#include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main(int argc,char *argv[]) { string str; while(cin>>str) cout<<str<<endl; return 0; }
執行情況如下所示:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out a //輸入a 然後按回車鍵 a ab //輸入ab,然後按下回車鍵 ab aaa bbb ccc //輸入aaa bbb ccc 按下回車鍵 aaa bbb ccc
按下 ctrl+d 就會退出上面的程序, 這裡while循環判斷 cin>>str 是否遇到 end-of-file 結束符,
當按下ctrl+d後, cin>>str 返回 false, 結束循環。
4、getline函數的使用
通過調用 getline函數可以一次輸入一行, 這裡需要注意的是:getline不會忽略開始的換行符,而是會
忽略最後的換行符,而且getline在遇到 空格、制表符的時候,不會結束一行的輸入,直到遇到endl換行符。
getline()接受兩個參數: getline(cin, str);
Exp:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main(int argc,char *argv[]) { string str; while(getline(cin,str)) cout<<str<<endl; return 0; }
執行結果如下:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out aaa bbb ccc ddd //輸入aaa bbb ccc ddd按下換行 aaa bbb ccc ddd //直接輸入換行 //直接輸入換行 12345 //輸入12345 按下換行 12345
這裡需要注意的是: getline不會忽略一行開頭的換行符,而且輸入後在string對象最後不會加上endl換行符。
5、string的操作
string類型提供了很多的操作, 下面我們來看一下:
string str;
str.size(); 返回str對象的長度
str.empty(); 判斷str是否是空字符串
str[n]; 下標操作,取其中的一個字符
str1 + str2;
str2 =str1;
str1 == str2
還有 != , <, <=, >,>= 這些比較操作,這些操作與整數型的操作的意義一樣,但是string的
比較是按照字典序,同時區分大小寫, 滿足下面的關系:A < a
Exp: 關於str.size() 函數計算的長度,
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2; cout<<str1.size()<<endl; cout<<sizeof("")<<endl; return 0; }
執行結果如下所示:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out 0 1
通過上面的例子可見, str.size()函數計算長度的時候並不包括最後的null字符'\0', 這一點需要注意。
還有一個特殊的地方: 就是 sizeof對 str對象的計算,得到的結果,與str.size 得到的結果不一樣,
因此需要注意。如下代碼所示:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2; cout<<str1.size()<<endl; cout<<sizeof("")<<endl; cout<<sizeof(str1)<<endl; return 0; }
上面代碼的執行結果如下所示:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out 0 1 4
這裡是因為 string對象會保留4個字節來存儲string對象的長度。
Exp: 關於 str.empty()函數的使用
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2; if(str1.empty()) { cout<<"str1 is a empty string"<<endl; } else { cout<<"str1 is not a empty string"<<endl; } return 0; }
執行結果如下:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out str1 is a empty string
這裡可以知道的是,如果string對象是一個空字符串,那麼 str.empty()函數返回true。
其實也可以通過 str.size( )==0 來判斷string對象是不是為空。因為 str.size()不會計算最後的 ‘\0'.
Exp: 關於 str[n] 的使用
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; str1="volanol"; for(string::size_type i=0; i != str1.size(); i++) { cout<<str1[i]<<endl; } return 0; }
執行結果如下:
[root@localhost cpp_src]# ./a.out v o l a n o l
這個代碼使用了上面說的: str1 = 字符串字面值的賦值方法, 同時使用了 str[n]的下標引用方法。
這裡有一點需要說明: string::size_type 是定義在string庫中的類型,這個類型專門用來計算string的長度
的。 同時還有一點: string對象的下標從0開始,到 str.size - 1 結束,就是說: 0<= n <= str.size() - 1
str[n]的下標還可以作為左值。如下所示:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str("volcanol"); cout<<"str is:"<<str<<endl; cout<<"after str[3]='y' the str is:"; str[3]='y'; cout<<str<<endl; return 0; }
執行結果如下:
[root@localhost cpp_src]# ./a.out str is:volcanol after str[3]='y' the str is:volyanol
Exp: 關於字符串的相加 str1 + str2
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2("hi,"); str1="volanol"; string str3= str2+ str1; cout<<str3<<endl; return 0; }
執行結果如下所示:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out hi,volanol
這段代碼,演示了 string類型的 str1 + str2 的效果,同時演示了 string str("volcanol"); 這樣的直接初始化
方式。
string對象的 + 操作可以與字符串字面值進行操作,如下:
Exp:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2("hi,"); str1="volanol"; string str3= str2+ str1; cout<<str3<<endl; string str4= str3 + "nice to meet you"; //字符串字面值 + 運算 cout<<str4<<endl; return 0; }
執行結果如下:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out hi,volanol hi,volanolnice to meet you
同時需要注意的是: + 操作符使用的時候,其左、右操作必須有一個是 string對象,否則是錯誤的。
例如:
1 #include <iostream> 2 #include <string> 3 4 using std::cin; 5 using std::cout; 6 using std::endl; 7 using std::string; 8 9 int main() 10 { 11 string str1; 12 string str2("hi,"); 13 14 str1="volanol"; 15 16 str1 = "hi," + str1; 17 18 str2= "hi,"+"volcanol"; 19 20 cout<<str1<<endl; 21 cout<<str2<<endl; 22 23 return 0; 24 }
編譯的情況如下所示:
[root@localhost cpp_src]# g++ test.cpp test.cpp: In function ‘int main()’: test.cpp:18: 錯誤:操作數類型 ‘const char [4]’ 和 ‘const char [9]’ 對雙目 ‘operator+’ 而言無效 [root@localhost cpp_src]#
可以發現 18 行出現錯誤了, 說 const char[4] 和 const char [9] 不能用雙目運算符進行計算,
原因上面的提示信息已經說的很明白了,const char類型不支持+ 操作。
關於書中的習題:
1、什麼是默認構造函數
默認構造函數是類構造對象是默認調用的構造函數,如果用戶不編寫用戶自定義的構造函數,則系統
默認會提供一個默認的構造函數。
2、例舉三種初始化string對象的方法
A: string str; 默認構造函數
B : string str("volcnaol"); 利用字符串字面值直接初始化
string str1(str); 利用string對象直接初始化
C string str = "volcanol"; 利用字符串字面值復制初始化
string str1 = str; 利用string對象復制初始化
D: string str(3, 'c');
方法D的例子如下:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str(3,'9'); cout<<str<<endl; return 0; }
執行結果如下:
[root@localhost cpp_src]# g++ test.cpp [root@localhost cpp_src]# ./a.out 999
3、 下面 s和s1的值分別是什麼
string s; int main() { string s1; }
這裡 s和s1 都是空字符串, 這個地方考察了一個知識點未初始化的對象的初值是什麼。 string對象
不初始化就是空字符串。
int a; int main() { int b; }
如上面所示, 則 a = 0; 而b將會是一個隨機值。 這是因為全局的內置類型如果不初始化,則系統默認會
初始化為0, 而局部變量的內置類型就會是一個隨機值。因此變量在定義的時候最好要初始化一下,保證在使用
之前就是有一個值,可以避免一些莫名其妙的錯誤。
習題4、編寫程序實現從標准輸入每次讀入一行文本, 然後改下程序每次讀入一個單詞。
讀入一行的程序:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str; getline(cin,str); cout<<str<<endl; return 0; }
修改為讀入一個單詞:
#include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str; //getline(cin,str); cin>>str; cout<<str<<endl; return 0; }
習題5: 編寫一個程序讀入兩個字符串,測試是否相等,如果不相等,則指出哪一個較大; 測試兩個是否等長,
如果不等長,則指出哪一個較長。
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2; cin>>str1>>str2; cout<<"str1 is:"<<str1<<endl; cout<<"str2 is:"<<str2<<endl; if(str1==str2) cout<<"str1 == str2"<<endl; else if(str1 > str2) cout<<"str1 > str"<<endl; else cout<<"str1 < str2"<<endl; if(str1.size() == str2.size()) cout<<"str1 and str2 have same length"<<endl; else if(str1.size() > str2.size()) cout<<"str1 is longger than str2"<<endl; else cout<<"str1 is shorter than strw"<<endl; return 0; }
習題6: 編寫一個程序讀入多個string對象,然後連接成1個更大的string對象輸出; 然後改下程序,將相鄰的string對象
用空格隔開。
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2; string str3; string str4; cin>>str1>>str2>>str3>>str4; string str5; str5=str1 + str2 + str3 + str4; cout<<str5<<endl; return 0; }
修改後的程序:
[root@localhost cpp_src]# cat test.cpp #include <iostream> #include <string> using std::cin; using std::cout; using std::endl; using std::string; int main() { string str1; string str2; string str3; string str4; cin>>str1>>str2>>str3>>str4; string str5; str5=str1 +" "+ str2+" " + str3+" " + str4; cout<<str5<<endl; return 0; }
7、下面的程序合法嗎,實現什麼功能
string s; cout<<s[0]<<endl;
合法,這個程序最終會輸出一個換行號。
這個地方尤其要注意,我開始的時候也做錯啦,經過測試才知道是對的。
最後一個題目不做啦,下次補上。
scanf("%f",weight);少一個&符號
C庫就是C函數庫,是一些跨平台的函數,可以完成許多功能。C函數庫包含以下頭文件
<assert.h><complex.h><ctype.h><errno.h><fenv.h><float.h><inttypes.h><iso646.h><limits.h><locale.h><math.h><setjmp.h><signal.h><stdarg.h><stdbool.h><stddef.h><stdint.h><stdio.h>
<stdlib.h><string.h><tgmath.h><time.h><wchar.h><wctype.h>
像stdio這樣的功能,是要依賴平台的調用來實現的,比如文件操作,不同的操作系統有不同的函數,但是C標准庫為我們定義了一個統一的抽象接口,方便了我們的程序。
就比如說,同樣是都是安全軟件。如卡巴斯基,瑞星什麼什麼的。
但是只有騰訊電腦管家這種安全軟件可以做到跨越各種安全平台,為用戶電腦帶來各項例如查殺病毒、電腦清理、電腦加速、電腦門診等的使用功能。
這下就明白了吧。
望采納哦。