C++
- 前言
- getline
- length, size
- c_str
- append, insert
- erase
- find
- substr
- isspace, isdigit
前言
C++是兼容C語言的,所以C++的字符串自然繼承C語言的一切字符串,但它也衍生出屬于自己的字符串類,即String類。String更像是一個容器,但它與容器還是有一些差別,我看網上很多人直接把它等同于一種容器,這種說法大概是有錯誤的。。。
string類的相關方法很多,下面我只記錄一下我個人常用到的一些方法,必然不詳實,僅供參考。
所有用到string類的地方都至少需要一個string的頭文件,如果還需要其它的,我們另外注明。
#include <string>
getline
從用戶端接收字符串方法其實挺多的,C語言中最常見的就是scanf函數了,類比這個函數,C++也可以用cin>>…的方式接收用戶輸入。但這兩者都只能接收一個單詞,或一個數字,因為它們會以空格符作為結尾。可以看看以下這個例子。
string s;cout <<"please enter a string: ";cin >> s;cout << s <<endl;
輸出結果如下:
以空格為結尾的接收輸入函數顯然不是我們所希望的,一句話,難免有許多空格。那么這時候就需要用到getline函數了,這個函數讀取的字符串會以換行符”\n“為結尾。
string s1;cout <<"please enter a string: ";getline(cin, s1);cout << s1 <<endl;
getline有兩個參數,第一個傳入參數是獲取字符串的地方,第二個傳入參數是字符串存放的地方。這里獲取用戶端輸入,所以第一個參數就是cin了。
程序運行結果如下:
length, size
length是C++早期讀取字符串長度的唯一方法,但后面為了兼容容器類,又推出了size方法。兩者的作用是一模一樣的。調用該函數會返回字符串的字符數,而非字節數。
用法也十分簡單:
string s1;cout <<"please enter a string: ";getline(cin, s1);cout << s1.length() <<endl;
程序運行結果如下,注意空格也算一個字符。
c_str
c_str方法的作用是把C++的字符串類轉化為常規的字符串,即變成可以用指針索引的字符串。因為有些函數要求傳入參數是" char * "。比如open函數。
看下面這個例程,c_str只能轉化為const char* 類型。并且由于字符指針指向的只能是一個字符,所以打印的時候需要用for循環打印出來。
string path = "/home/object_file";const char *f;f = path.c_str(); for(int i=0; i<path.length(); i++){cout<< f[i];}cout<<"\n";
不過如果用C語言的printf函數,倒可以免去使用for循環,直接用%s告訴計算機這是一個字符串即可。
string path = "/home/object_file";const char *f;f = path.c_str();printf("%s \n", f);
有string類轉化為const char*,那放過來char *轉化為string類也可以。操作十分簡單,只需要直接賦值就行。
char temp[15] = "hello world";string s = temp;cout << s << endl;
append, insert
append方法和insert方法都是在原來的字符串的基礎上添加某些東西,但前者是添加在字符串后面,后者則可以添加到指定位置。它們的用法都比較簡單,直接看以下例子。
string s1 = "hello ";string s2 = "word";s1.append("wrold");s2.insert(0, "add a "); //第一個參數是插入的位置,第二個參數是插入的字符串cout <<"s1: "<< s1 << endl; cout <<"s2: "<< s2 << endl;
以上程序的運行情況如下:
s1: hello world
s2: add a word
erase
erase方法用來擦除字符串中的某些字符,在處理數據的時候還挺有用的。
直接看一個例子:
string s = "hello world!";s.erase(3, 2);cout << s << endl;
程序運行結果如下:
可見,erase第一個傳入參數是起始位置,第二個傳入參數擦除的字符個數。如果沒有添加第二個參數則視為,在擦除起始位置之后的全部字符。可以看個例子:
string s = "hello world!";s.erase(3);cout << s << endl; //打印結果是hel
熟悉C++容器的朋友大概會發現,這與容器的erase方法有一些不一樣。以vector為例,erase(begin, end)的第一個參數是要擦除的起始位置,第二個位置是要擦除的結束位置,如果第二個參數不寫,就默認只擦除一個成員。
find
find方法是從字符串中查找某個特定的字符,并且返回該字符第一次出現時的位置。當然find方法也有很多衍生方法,比如find_first_of, find_last_of等等。而對于這些衍生方法,大家有興趣可以自行查閱相關資料。我這里就只說一下find的一些常規應用。
string s = "hello world!";int loc = s.find("o");cout << loc << endl;
在"hello world!"這個字符串中,"o"第一個出現的位置是4,所以打印結果就是4。
而如果我們像知道"o"第二次出現的地方呢?可以參考以下這個例程:
string s = "hello world!";int loc = s.find("o");int cnt = 1;while(loc != string::npos){if(cnt == 2) break;loc = s.find("o", loc+1);cnt ++;}cout << loc <<endl;
程序輸出結果如下:
在"hello world!"這個字符中,"o"第二次出現的位置確實是7,符合預期。
那么總結一下,find有兩個傳入參數,第一個傳入參數是期望查找的字符,第一個傳入參數是字符串中搜索區域的起始位置,如果沒有這個參數,則默認從頭開始搜索。
find方法的返回值就是被搜索字符首次出現的位置,如果沒有找到該字符,則返回string::npos。
substr
substr方法用于截取字符串中的某一段,它有兩個參數,第一個參數是截取區間的起點,第二個參數是截取區間的終點。返回值是所截取出來的字符串。
以下例程的作用是將"hello world!"中的hello截取出來:
string s = "hello world!";string sp = s.substr(0, 5);cout << sp << endl;
isspace, isdigit
isspace和isdigit分別是判斷字符串中的空格和數字的函數,調用這兩個函數的時候需要添加頭文件cctype。其實這兩個函數不是C++string類特有的,C語言中的字符串也可以用。
#include <cctype>
看個例子吧,該例子欲將"hello world!"中的空格抹去。
string s = "hello world!";for(int i=0; i<s.length(); i++){if(isspace(s[i])){s.erase(i, 1);i--;}}cout << s <<endl;
isspace的返回值是一個int類型,如果檢查到空格就返回一個非零數據,否則返回0.
突然想到另一種消除空格方法,也一并寫出來吧。
string s = "hello world!";int cnt = 0;for(char i : s){if(i == ' '){s.erase(cnt, 1);cnt--;}cnt ++;}cout << s <<endl;
接下來再來看看isdigit的用法,isdigit和isspace的返回值很像,都是檢查到目標則返回非零數字,否則返回0.
在本例程中,我欲將字符串"hello 123 world!"的數字打印出來。
string s = "hello 123 world!";for(int i=0; i<s.length(); i++){if(isdigit(s[i])){int temp = s[i] - '0';cout<< temp;}}cout <<"\n";
輸出結果如下: