https://blog.csdn.net/tengfei461807914/article/details/52203202 string是C++標準庫的一個重要的部分,主要用於字元串處理。可以使用輸入輸出流方式直接進行操作,也可以通過文件等手段進行操作。同時C++的演算法庫對string也有著很好 ...
https://blog.csdn.net/tengfei461807914/article/details/52203202
string是C++標準庫的一個重要的部分,主要用於字元串處理。可以使用輸入輸出流方式直接進行操作,也可以通過文件等手段進行操作。同時C++的演算法庫對string也有著很好的支持,而且string還和c語言的字元串之間有著良好的介面。雖然也有一些弊端,但是瑕不掩瑜。
其中使用的代碼多數都是來自cpp官網,因為例子非常全。
聲明和初始化方法:
想使用string首先要在頭文件當中加入< string >
聲明方式也很簡單
聲明:
string s;//聲明一個string 對象
string ss[10];//聲明一個string對象的數組
- 1
- 2
初始化:
使用等號的初始化叫做拷貝初始化,不使用等號的初始化叫做直接初始化。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string s;//預設初始化,一個空字元串
string s1("ssss");//s1是字面值“ssss”的副本
string s2(s1);//s2是s1的副本
string s3=s2;//s3是s2的副本
string s4(10,'c');//把s4初始化
string s5="hiya";//拷貝初始化
string s6=string(10,'c');//拷貝初始化,生成一個初始化好的對象,拷貝給s6
//string s(cp,n)
char cs[]="12345";
string s7(cs,3);//複製字元串cs的前3個字元到s當中
//string s(s2,pos2)
string s8="asac";
string s9(s8,2);//從s2的第二個字元開始拷貝,不能超過s2的size
//string s(s2,pos2,len2)
string s10="qweqweqweq";
string s11(s10,3,4);//s4是s3從下標3開始4個字元的拷貝,超過s3.size出現未定義
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
字元串處理:
substr操作:
註意substr沒有迭代器作為參數的操作
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string s="abcdefg";
//s.substr(pos1,n)返回字元串位置為pos1後面的n個字元組成的串
string s2=s.substr(1,5);//bcdef
//s.substr(pos)//得到一個pos到結尾的串
string s3=s.substr(4);//efg
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
如果輸入的位置超過字元的長度,會拋出一個out_of_range的異常
insert操作:
代碼來自cpp官網,經過自己的整理
註意用迭代器當參數和無符號數當參數的區別
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string str="to be question";
string str2="the ";
string str3="or not to be";
string::iterator it;
//s.insert(pos,str)//在s的pos位置插入str
str.insert(6,str2); // to be the question
//s.insert(pos,str,a,n)在s的pos位置插入str中插入位置a到後面的n個字元
str.insert(6,str3,3,4); // to be not the question
//s.insert(pos,cstr,n)//在pos位置插入cstr字元串從開始到後面的n個字元
str.insert(10,"that is cool",8); // to be not that is the question
//s.insert(pos,cstr)在s的pos位置插入cstr
str.insert(10,"to be "); // to be not to be that is the question
//s.insert(pos,n,ch)在s.pos位置上面插入n個ch
str.insert(15,1,':'); // to be not to be: that is the question
//s.insert(s.it,ch)在s的it指向位置前面插入一個字元ch,返回新插入的位置的迭代器
it = str.insert(str.begin()+5,','); // to be, not to be: that is the question
//s.insert(s.it,n,ch)//在s的it所指向位置的前面插入n個ch
str.insert (str.end(),3,'.'); // to be, not to be: that is the question...
//s.insert(it,str.ita,str.itb)在it所指向的位置的前面插入[ita,itb)的字元串
str.insert (it+2,str3.begin(),str3.begin()+3); // to be, or not to be: that is the question...
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
erase操作:
用來執行刪除操作
刪除操作有三種
- 指定pos和len,其中pos為為起始位置,pos以及後面len-1個字元串都刪除
- 迭代器,刪除迭代器指向的字元
- 迭代器範圍,刪除這一範圍的字元串,範圍左閉右開
代碼來自cpp官網
#include <iostream>
#include <string>
int main ()
{
std::string str ("This is an example sentence.");
std::cout << str << '\n';
// "This is an example sentence."
str.erase (10,8); // ^^^^^^^^
//直接指定刪除的字元串位置第十個後面的8個字元
std::cout << str << '\n';
// "This is an sentence."
str.erase (str.begin()+9);// ^
//刪除迭代器指向的字元
std::cout << str << '\n';
// "This is a sentence."
// ^^^^^
str.erase (str.begin()+5, str.end()-9);
//刪除迭代器範圍的字元
std::cout << str << '\n';
// "This sentence."
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
append和replace操作:
append函數可以用來在字元串的末尾追加字元和字元串。由於string重載了運算符,也可以用+=操作實現
repalce顧名思義,就是替換的意思,先刪除,後增加。
代碼來自cpp官網,附上自己的解釋
#include <iostream>
#include <string>
int main ()
{
std::string str;
std::string str2="Writing ";
std::string str3="print 10 and then 5 more";
//直接追加一個str2的字元串
str.append(str2); // "Writing "
//後面追加str3第6個字元開始的3個字元串
str.append(str3,6,3); // "10 "
//追加字元串形參的前5個字元
str.append("dots are cool",5); // "dots "
//直接添加
str.append("here: "); // "here: "
//添加10個'.'
str.append(10u,'.'); // ".........."
//添加str3迭代器範圍的字元串
str.append(str3.begin()+8,str3.end()); // " and then 5 more"
//最後這個比較特殊,意思是添加5個'A',實際上參數裡面的65對應的asc碼就是65
str.append<int>(5,65); // "....."
//字元串追加也可以用重載運算符實現
str+="lalala";
std::cout << str << '\n';
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
replace的使用方法,replace支持使用無符號整數尋找位置,也支持用迭代器尋找位置
#include <iostream>
#include <string>
int main ()
{
std::string base="this is a test string.";
std::string str2="n example";
std::string str3="sample phrase";
std::string str4="useful.";
// replace signatures used in the same order as described above:
// Using positions: 0123456789*123456789*12345
std::string str=base; // "this is a test string."
//第9個字元以及後面的4個字元被str2代替
str.replace(9,5,str2); // "this is an example string." (1)
//第19個字元串以及後面的5個字元用str的第7個字元以及後面的5個字元代替
str.replace(19,6,str3,7,6); // "this is an example phrase." (2)
//第8個字元以及後面的9個字元用字元串參數代替
str.replace(8,10,"just a"); // "this is just a phrase." (3)
//第8個字元以及後面的5個字元用字元串參數的前7個字元替換
str.replace(8,6,"a shorty",7); // "this is a short phrase." (4)
//第22以及後面的0個字元用3個嘆號替換
str.replace(22,1,3,'!'); // "this is a short phrase!!!" (5)
//迭代器的原理同上
// Using iterators: 0123456789*123456789*
str.replace(str.begin(),str.end()-3,str3); // "sample phrase!!!" (1)
str.replace(str.begin(),str.begin()+6,"replace"); // "replace phrase!!!" (3)
str.replace(str.begin()+8,str.begin()+14,"is coolness",7); // "replace is cool!!!" (4)
str.replace(str.begin()+12,str.end()-4,4,'o'); // "replace is cooool!!!" (5)
str.replace(str.begin()+11,str.end(),str4.begin(),str4.end());// "replace is useful." (6)
std::cout << str << '\n';
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
以上的replace操作可以用insert和erase的操作組合替換,但是replace操作更加方便。
assign操作:
assign操作在一起列容器當中都存在,比如vector等等。是一個很基本的操作函數,string使用assign可以靈活的對其進行賦值。
代碼來自cpp官網
#include <iostream>
#include <string>
int main ()
{
std::string str;
std::string base="The quick brown fox jumps over a lazy dog.";
// used in the same order as described above:
//直接把base賦值給str
str.assign(base);
std::cout << str << '\n';
//把base第10個字元以及後面的8個字元賦給str
str.assign(base,10,9);
std::cout << str << '\n'; // "brown fox"
//把參數中的0到6個字元串賦給str
str.assign("pangrams are cool",7);
std::cout << str << '\n'; // "pangram"
//直接使用參數賦值
str.assign("c-string");
std::cout << str << '\n'; // "c-string"
//給str賦值10個'*'字元
str.assign(10,'*');
std::cout << str << '\n'; // "**********"
//賦值是10個'-'
str.assign<int>(10,0x2D);
std::cout << str << '\n'; // "----------"
//指定base迭代器範圍的字元串
str.assign(base.begin()+16,base.end()-12);
std::cout << str << '\n'; // "fox jumps over"
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
string的搜索操作:
string類中提供了很多性能優秀,使用方便的成員方法。而且在泛型演算法當中也有很多實用的技巧。
find和rfind函數:
find函數主要是查找一個字元串是否在調用的字元串中出現過,大小寫敏感。
代碼來自cpp官網
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
std::string str ("There are two needles in this haystack with needles.");
std::string str2 ("needle");
// different member versions of find in the same order as above:
//在str當中查找第一個出現的needle,找到則返回出現的位置,否則返回結尾
std::size_t found = str.find(str2);
if (found!=std::string::npos)
std::cout << "first 'needle' found at: " << found << '\n';
//在str當中,從第found+1的位置開始查找參數字元串的前6個字元
found=str.find("needles are small",found+1,6);
if (found!=std::string::npos)
std::cout << "second 'needle' found at: " << found << '\n';
//在str當中查找參數中的字元串
found=str.find("haystack");
if (found!=std::string::npos)
std::cout << "'haystack' also found at: " << found << '\n';
//查找一個字元
found=str.find('.');
if (found!=std::string::npos)
std::cout << "Period found at: " << found << '\n';
//組合使用,把str2用參數表中的字元串代替
// let's replace the first needle:
str.replace(str.find(str2),str2.length(),"preposition");
std::cout << str << '\n';
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
rfind函數就是找最後一個出現的匹配字元串,返回的位置仍然是從前往後數的。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
std::string str ("The sixth sick sheik's sixth sheep's sick.");
std::string key ("sixth");// ^
//rfind是找最後一個出現的匹配字元串
std::size_t found = str.rfind(key);
if (found!=std::string::npos)
{
cout<<found<<endl;//輸出23
str.replace (found,key.length(),"seventh");//找到的sixth替換成seventh
}
std::cout << str << '\n';
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
查找的效率非常高,我沒看過stl源碼剖析,但是感覺是用kmp實現的。呵呵,可以自己寫一個。
find_….of函數:
- find_first_of(args) 查找args中任何一個字元第一次出現的位置
- find_last_of(args) 最後一個出現的位置
- find_fist_not_of(args) 查找第一個不在args中的字元
- find_last_not_of 查找最後一個不在args中出現的字元
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
std::string str1 ("Please, replace the vowels in this sentence by asterisks.");
std::size_t found1 = str1.find_first_of("aeiou");
//把所有母音找出來用*代替
while (found1!=std::string::npos)
{
str1[found1]='*';
found1=str1.find_first_of("aeiou",found1+1);
}
std::cout << str1 << '\n';
//在str2中找到第一個不是消協英文字母和空格的字元
std::string str2 ("look for non-alphabetic characters...");
std::size_t found2 = str2.find_first_not_of("abcdefghijklmnopqrstuvwxyz ");
if (found2!=std::string::npos)
{
std::cout << "The first non-alphabetic character is " << str2[found2];
std::cout << " at position " << found2 << '\n';
}
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
find_last_of和find_last_not_of與first基本相同,就不寫例子代碼了。
比較與轉換:
類似c語言的字元串比較函數strcmp函數一樣,支持字元串比較操作,同時也類似python、C#語言中的函數一樣,支持把數字和字元串轉換。有些特性是C++11當中才有。
註意編譯器bug:
在MinGW編譯器當中如果版本低於3.8,雖然支持c++11但是裡面有一個bug,就是不支持字元串和數組的轉換!要更新MinGW的版本才可以,或者直接使用g++。
compare函數:
和strcmp函數一樣,如果兩個字元串相等,那麼返回0,調用對象大於參數返回1,小於返回-1。
在compare當中還支持部分比較,裡面有6個參數可以設置。
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string s1="123",s2="123";
cout<<s1.compare(s2)<<endl;//0
s1="123",s2="1234";
cout<<s1.compare(s2)<<endl;//-1
s1="1234",s2="123";
cout<<s1.compare(s2)<<endl;//1
std::string str1 ("green apple");
std::string str2 ("red apple");
if (str1.compare(str2) != 0)
std::cout << str1 << " is not " << str2 << '\n';
//str1的第6個字元以及後面的4個字元和參數比較
if (str1.compare(6,5,"apple") == 0)
std::cout << "still, " << str1 << " is an apple\n";
if (str2.compare(str2.size()-5,5,"apple") == 0)
std::cout << "and " << str2 << " is also an apple\n";
//str1的第6個字元以及後面的4個字元和str2的第4個字元以及後面的4個字元比較
if (str1.compare(6,5,str2,4,5) == 0)
std::cout << "therefore, both are apples\n";
return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
由於string重載了運算符,可以直接用>,<,==來進行比較,也很方便。
數值轉換:
在io的部分有過數值和字元串相互轉換的例子,使用的是stringstream函數,在c++11當中有定義好的現成的函數取調用,非常方便。
string和數值轉換 | |
---|---|
to_string(val) | 把val轉換成string |
stoi(s,p,b) | 把字元串s從p開始轉換成b進位的int |
stol(s,p,b) | long |
stoul(s,p,b) | unsigned long |
stoll(s,p,b) | long long |
stoull(s,p,b) | unsigned long long |
stof(s,p) | float |
stod(s,p) | double |
stold(s,p) | long double |
//註意,下段代碼在MinGw中會報錯!即使使用c++11編譯也一樣,無法識別to_string!
#include <bits/stdc++.h>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
string s1;
s1=to_string(100);
cout<<s1<<endl;
int a=stoi(s1,0,10)+1;
cout<<a<<endl;
return 0;
}