1 string字符串容器和泛型算法 1.1 STL顺序容器
参考顺序容器部分
访问元素
也可以使用迭代器 访问元素。
at 会进行安全检查抛出异常。
[]下标运算符 不会进行检查。
back(),front()
添加元素
总共有6+3=9种插入方法。insert有额外的两种范围插入方法。
在尾部添加元素push_back(),emplace_back()
在头部添加元素push_front(),emplace_front()
在中间添加元素insert(),emplace()
insert方法提供了范围插入的方法。中间插入一个元素。在给定的一个迭代器之前插入一个值。中间插入多个元素。在给定的迭代器之前插入范围迭代器内的元素。
删除元素
back、front、push_back、push_front、pop_back、pop_front、emplace_front、emplace_back 。是一组首尾相关的插入操作。
insert、emplace、at、erase 。是一组随机的操作。
重构容器
1.2 STL泛型算法
string 对象也可以看作一个顺序容器,它支持随机访问迭代器,也有 begin 和 end 等成员函数。STL 中的许多算法也适用于 string 对象。下面是用 STL 算法操作 string 对象的程序示例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <algorithm> #include <string> using namespace std;int main () { string s ("afgcbed" ) ; string::iterator p = find (s.begin (), s.end (), 'c' ); if (p!= s.end ()) cout << p - s.begin () << endl; sort (s.begin (), s.end ()); cout << s << endl; next_permutation (s.begin (), s.end ()); cout << s << endl; return 0 ; }
2 string字符串操作 2.1 字符串创建
这三种初始化的恶魔是,在assign、find、append、replace、insert函数中,也在使用。就如同顺序容器中的初始化方法,在顺序容器的其他的操作中也是通用的。
1 2 3 4 string s1 () ; string s2 ("Hello" ) ; string s3 (4 , 'K' ) ; string s4 ("12345" , 1 , 3 ) ;
为称呼方便,本教程后文将从字符串下标 n 开始、长度为 m 的字符串称为“子串(n, m)”。
string 类没有接收一个整型参数或一个字符型参数的构造函数。下面的两种写法是错误的:
1 2 string s1 ('K' ) ;string s2 (123 ) ;
2.2 字符串赋值
可以用 char* 类型的变量、常量,以及 char 类型的变量、常量对 string 对象进行赋值。例如:
1 2 3 string s1; s1 = "Hello" ; s2 = 'K' ;
string 类还有 assign 成员函数,可以用来对 string 对象赋值。assign 成员函数返回对象自身的引用。例如:
1 2 3 4 5 string s1 ("12345" ) , s2 ;s3. assign (s1); s2. assign (s1, 1 , 2 ); s2. assign (4 , 'K' ); s2. assign ("abcde" , 2 , 3 );
2.3 字符串交换
swap 成员函数可以交换两个 string 对象的内容。例如:
1 2 string s1 ("West”), s2(" East"); s1.swap(s2); // s1 = " East",s2 = " West"
2.4 字符串长度
int length() 成员函数返回字符串的长度。
int size() 成员函数可以实现同样的功能。
2.5 字符串比较
可以用 <、<=、==、!=、>=、> 运算符比较 string 对象
compare 成员函数可用于比较字符串。compare 成员函数有以下返回值:
小于 0 表示当前的字符串小;
等于 0 表示两个字符串相等;
大于 0 表示另一个字符串小。
1 2 3 4 5 6 7 string s1 ("hello" ) , s2 ("hello, world" ) ;int n = s1. compare (s2);n = s1. compare (1 , 2 , s2, 0 , 3 ); n = s1. compare (0 , 2 , s2); n = s1. compare ("Hello" ); n = s1. compare (1 , 2 , "Hello" ); n = s1. compare (1 , 2 , "Hello" , 1 , 2 );
2.6 查找字符串(字符)
string 类有一些查找子串和字符的成员函数,它们的返回值都是子串或字符在 string 对象字符串中的位置(即下标)。
如果查不到,则返回 string::npos 。string: :npos 是在 string 类中定义的一个静态常量。这些函数如下:
find:从前往后查找子串或字符出现的位置。
rfind:从后往前查找子串或字符出现的位置。
find_first_of:从前往后查找何处出现另一个字符串中包含的字符。
find_last_of:从后往前查找何处出现另一个字符串中包含的字符。
find_first_not_of:从前往后查找何处出现另一个字符串中没有包含的字符。
find_last_not_of:从后往前查找何处出现另一个字符串中没有包含的字符。
所有的字符串查找方法重载了以下四种类型:pos表示开始查找的位置。n表示查找匹配的次数。返回值是整数索引。
string (1) size_t find (const string& str, size_t pos = 0) const noexcept;
c-string (2) size_t find (const char* s, size_t pos = 0) const;
buffer (3) size_t find (const char* s, size_t pos, size_type n) const;
character (4) size_t find (char c, size_t pos = 0) const noexcept;
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 #include <iostream> #include <string> using namespace std;int main () { string s1 ("Source Code" ) ; int n; if ((n = s1.f ind('u' )) != string::npos) cout << "1) " << n << "," << s1. substr (n) << endl; if ((n = s1.f ind("Source" , 3 )) == string::npos) cout << "2) " << "Not Found" << endl; if ((n = s1.f ind("Co" )) != string::npos) cout << "3) " << n << ", " << s1. substr (n) << endl; if ((n = s1.f ind_first_of("ceo" )) != string::npos) cout << "4) " << n << ", " << s1. substr (n) << endl; if ((n = s1.f ind_last_of('e' )) != string::npos) cout << "5) " << n << ", " << s1. substr (n) << endl; if ((n = s1.f ind_first_not_of("eou" , 1 )) != string::npos) cout << "6) " << n << ", " << s1. substr (n) << endl; return 0 ; }
2.7 字符串拼接
+和+=运算符对string 对象执行字符串的连接操作
append 成员函数,可以用来向字符串后面添加内容。append 成员函数返回对象自身的引用。
string& append (const string& str);
string& append (const string& str, size_t subpos, size_t sublen);
string& append (const char* s);
string& append (const char* s, size_t n);
string& append (size_t n, char c);
string& append (InputIterator first, InputIterator last);
1 2 3 4 5 string s1 ("123" ) , s2 ("abc" ) ;s1. append (s2); s1. append (s2, 1 , 2 ); s1. append (3 , 'K' ); s1. append ("ABCDE" , 2 , 3 );
2.8 字符串剪切
substr 成员函数可以用于求子串 (n, m),原型如下。调用时,如果省略 m 或 m 超过了字符串的长度,则求出来的子串就是从下标 n 开始一直到字符串结束的部分。例如:
string substr (size_t pos = 0, size_t len = npos) const;
1 2 3 string s1 = "this is ok" ; string s2 = s1. substr (2 , 4 ); s2 = s1. substr (2 );
2.9 字符串替换
replace 成员函数可以对 string 对象中的子串进行替换,返回值为对象自身的引用。
string (1) string& replace (size_t pos, size_t len, const string& str);
string& replace (const_iterator i1, const_iterator i2, const string& str);
substring (2) string& replace (size_t pos, size_t len, const string& str, size_t subpos, size_t sublen);
c-string (3) string& replace (size_t pos, size_t len, const char* s);
string& replace (const_iterator i1, const_iterator i2, const char* s);
buffer (4) string& replace (size_t pos, size_t len, const char* s, size_t n);
string& replace (const_iterator i1, const_iterator i2, const char* s, size_t n);
fill (5) string& replace (size_t pos, size_t len, size_t n, char c);
string& replace (const_iterator i1, const_iterator i2, size_t n, char c);
range (6) string& replace (const_iterator i1, const_iterator i2, InputIterator first, InputIterator last);
initializer list (7) string& replace (const_iterator i1, const_iterator i2, initializer_list il);
1 2 3 4 5 6 7 8 9 string s1 ("Real Steel" ) ;s1. replace (1 , 3 , "123456" , 2 , 4 ); cout << s1 << endl; string s2 ("Harry Potter" ) ;s2. replace (2 , 3 , 5 , '0' ); cout << s2 << endl; int n = s2.f ind("OOOOO" ); s2. replace (n, 5 , "XXX" ); cout << s2 < < endl;
2.10 字符串插入
1 2 3 4 string s1 ("Limitless" ) , s2 ("00" ) ;s1. insert (2 , "123" ); s1. insert (3 , s2); s1. insert (3 , 5 , 'X' );
2.11 字符串删除
erase 成员函数可以删除 string 对象中的子串,返回值为对象自身的引用。如果使用了迭代器。则返回值为指向删除序列后的第一个字符的迭代器。
sequence (1)string& erase (size_t pos = 0, size_t len = npos);
character (2)iterator erase (const_iterator p);
range (3)iterator erase (const_iterator first, const_iterator last);
1 2 3 string s1 ("Real Steel" ) ;s1. erase (1 , 3 ); s1. erase (5 );
3 字符串转换 3.1 数值转换
s表示字符串
p表示在转换过程中遇到的第一个转换不了的字符。p可以得到它的下标。
b表示转换的默认进制。默认是10进制
函数
说明
string string to_string(val)
一组重载函数。返回val值的string表示。
int stoi(string s,size_t*p,int b)
返回整形
long stol(s,p,b)
返回long
unsigned long stoul(s,p,b)
返回unsigned long
long long stoll(s,p,b)
返回longlong
unsigned long long stoull(s,p,b)
返回unsigned longlong
float stof(s,p)
返回float
double stod(s,p)
返回double
long double stold(s,p)
返回long double
3.2 C字符串转string 1 2 str ="helloworld"; string s(str);
3.3 string转C风格字符串 1 2 string s("helloworld"); const char * str = s.c_str();
4 字符串流对象
将string视为特殊的字符串流。使用流对象的方法处理字符串。
使用流对象 istringstream 和 ostringstream,可以将 string 对象当作一个流进行输入输出。使用这两个类需要包含头文件 sstream。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 #include <iostream> #include <sstream> #include <string> using namespace std;int main () { string src ("Avatar 123 5.2 Titanic K" ) ; istringstream istrStream (src) ; string s1, s2; int n; double d; char c; istrStream >> s1 >> n >> d >> s2 >> c; ostringstream ostrStream; ostrStream << s1 << endl << s2 << endl << n << endl << d << endl << c <<endl; cout << ostrStream.str (); return 0 ; }
5 正则匹配
在正则表达式部分,有专门针对string的正则匹配搜索算法。
6 C字符串 头文件 1 2 3 #include<cstring> #include<cstdlib> #include<cstdio>
方法
名称
函数 & 目的
strcpy(s1, s2);
复制字符串 s2 到字符串 s1。
strcat(s1, s2);
连接字符串 s2 到字符串 s1 的末尾。连接字符串也可以用 + 号,例如:string str1 = “runoob”;string str2 = “google”;string str = str1 + str2;
strlen(s1);
返回字符串 s1 的长度。
strcmp(s1, s2);
如果 s1 和 s2 是相同的,则返回 0;如果 s1<s2 则返回值小于 0;如果 s1>s2 则返回值大于 0。
strchr(s1, ch);
返回一个指针,指向字符串 s1 中字符 ch 的第一次出现的位置。
strstr(s1, s2);
返回一个指针,指向字符串 s1 中字符串 s2 的第一次出现的位置。
7 字符串分割的两种处理方式 字符串流分割
使用getline()有分隔符的读入。和istringstream方法。对字符串进行分割。
1 getline (istream,string,delim)
1 2 3 4 5 6 7 istringstream is (ss) ;string temp; while (getline (is,temp,' ' )){ if (temp=="" )continue ; st.push (temp); }
字符串方法分割
使用find(patter,pos)和substr(pos,length)两个函数进行查找和剪切。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 string strs =" adb dai fei af" ; string pattern = " " ; size_t start_pos=0 ;size_t end_pos = strs.find (pattern,start_pos);vector<string> vec; string temp; while (end_pos != string::npos){ cout<<start_pos<<"--" <<end_pos<<endl; if (start_pos!=end_pos){ temp = strs.substr (start_pos,end_pos-start_pos); vec.push_back (temp); } start_pos = end_pos+1 ; end_pos = strs.find (pattern,start_pos); } vec.push_back (strs.substr (start_pos,strs.size ()-start_pos)); for (auto a : vec){ cout<<"name:" <<a<<":end" <<endl; } return 0 ;
8 字符串格式化的两种处理方式 C-sprintf格式化字符串 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <stdio.h> using std::string;string haha ("haha" ) ;int num = 3 ;string fmt ("test string: %s. test number: %d" ) ;char targetString[1024 ];int realLen = sprintf ( targetString, sizeof (targetString), fmt.c_str (), haha.c_str (), num );
字符串流格式化 1 2 3 4 5 6 7 8 9 10 11 12 使用stringstream格式化字符串 #include <sstream> using std::stringstream;string haha ("haha" ) ;int num = 3 ;stringstream fmt; fmt << "test string: " << haha << ". test number: " << num; string targetString = fmt.str ();
9 字符串匹配match和查找search的多种实现方法
match整个字符串符合要求
search找到符合要求的字符串子串。
循环暴力查找
暴力
成员函数find查找
参考 字符串find
模板函数find查找
参考 算法
正则表达式匹配
见正则表达式
10 字符串替换的多重实现方法 暴力替换 1 2 3 4 5 6 7 8 9 10 11 12 13 string replaceSpace1(string s) { string result; for(int i=0;i<s.size();i++){ if(s[i]==' '){ result.append("%20"); } else{ result.push_back(s[i]); } } return result; }
容器库的erase和insert替换 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 使用字符串库STL容器库的方法试一下 string replaceSpace2(string s) { auto beg = s.begin(); auto end = s.end(); while(beg<end){ if(*beg==' '){ beg = s.erase(beg); beg = s.insert(beg,{'%','2','0'}); end = s.end(); } else{ beg++; } } return s; }
string对象的find和replace替换 1 2 3 4 5 6 7 8 9 10 11 // 使用字符串库STL容器库的find和replace试一下 string replaceSpace(string s) { int pos=0; string str="%20"; pos=s.find(" ",pos); while(pos!=string::npos){ s.replace(pos,1,str); pos=s.find(" ",pos); } return s; }