2.3 string基本字符系列容器
C语言只提供了一个char类型用来处理字符,而对于字符串,只能通过字符串数组来处理,显得十分不便。C++STL提供了string基本字符系列容器来处理字符串,可以把string理解为字符串类,它提供了添加、删除、替换、查找和比较等丰富的方法。
虽然使用vector<char>这样的向量也可以处理字符串,但功能比不上string。向量的元素类型可以是string,如vector<string>这样的向量,实际上就类似于C语言中的字符串数组。
使用string容器,需要头文件包含声明“#include <string>”。string文件在C:\Program Files\Microsoft Visual Studio\VC98\Include文件夹中可以找到。
2.3.1 创建string对象
下面这条语句创建了字符串对象s, s是一个空字符串,其长度为0:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; cout<<s.length()<<endl; return 0; }
运行结果:
0
2.3.2 给string对象赋值
给string对象赋值一般有两种方式。
(1)直接给字符串对象赋值,如:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="hello, C++STL."; cout<<s<<endl; return 0; }
运行结果:
hello, C++STL.
(2)更常用的方法是,把字符指针赋给一个字符串对象:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; char ss[5000]; //scanf的输入速度比cin快得多 //scanf是C语言的函数,不支持string对象 scanf("%s", &ss); //把整个字符数组赋值给string对象 s=ss; //输出字符对象 cout<<s<<endl; return 0; }
运行结果(先从键盘上输入“hello, string.”):
hello, string. hello, string.
2.3.3 从string对象尾部添加字符
在string对象的尾部添加一个字符(char),采用“+”操作符即可,具体应用如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s=s+'a'; s=s+'b'; s=s+'c'; cout<<s<<endl; return 0; }
运行结果:
abc
2.3.4 从string对象尾部追加字符串
从尾部追加的方式有两种。
(1)直接采用“+”操作符,代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s=s+"abc"; s=s+"123"; cout<<s<<endl; return 0; }
运行结果:
abc123
(2)采用append()方法,代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s.append("abc"); s.append("123"); cout<<s<<endl; return 0; }
运行结果:
abc123
2.3.5 给string对象插入字符
可以使用insert()方法把一个字符插入到迭代器位置之前,代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="123456"; //定义迭代器 string::iterator it; //迭代器位置为字符串首 it=s.begin(); //把字符’p’插入到第1个字符前(注意,字符位置是从0开始计数) s.insert(it+1, 'p'); cout<<s<<endl; return 0; }
运行结果:
1p23456
2.3.6 访问string对象的元素
一般使用下标方式随机访问string对象的元素,下标是从0开始计数的。另外,string对象的元素是一个字符(char),这点一定要清楚。代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="abc123456"; //输出string对象的首元素 cout<<s[0]<<endl; //两个相同的字符相减值为0 cout<<s[0]-'a'<<endl; return 0; }
运行结果:
a 0
2.3.7 删除string对象的元素
(1)清空一个字符串,则直接给它赋空字符串即可。
(2)使用erase()方法删除迭代器所指的那个元素或一个区间中的所有元素。代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="abc123456"; //定义迭代器变量,指向字符串对象首元素 string::iterator it=s.begin(); //删除第3个元素,元素位置从0开始计数 s.erase(it+3); cout<<s<<endl; //删除0~4区间的所有元素 s.erase(it, it+4); cout<<s<<endl; //清空字符串 s=""; //输出字符串的长度 cout<<s.length()<<endl; return 0; }
运行结果:
abc23456 3456 0
2.3.8 返回string对象的长度
采用length()方法可返回字符串的长度;采用empty()方法,可返回字符串是否为空,如果字符串为空,则返回逻辑真,即1,否则,返回逻辑假,即0。代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="abc123456"; //输出字符串的长度 cout<<s.length()<<endl; //清空字符串 s=""; //判断字符串是否为空 cout<<s.empty()<<endl; return 0; }
运行结果:
9 1
2.3.9 替换string对象的字符
使用replace()方法可以很方便地替换string对象中的字符,replace()方法的重载函数相当多,常用的只有一两个,具体代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="abc123456"; //从第3个开始,将连续的3个字符替换为“good” //即将“abc”替换为“good” s.replace(3,3, "good"); cout<<s<<endl; return 0; }
运行结果:
abcgood456
2.3.10 搜索string对象的元素或子串
采用find()方法可查找字符串中的第一个字符元素(char,用单引号界定)或者子串(用双引号界定),如果查到,则返回下标值(从0开始计数),如果查不到,则返回4294967295。
find()方法有很多重载函数,下面的代码,仅举出了一种用法。
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="cat dog cat"; //查找第一个字符‘c',返回下标值 cout<<s.find('c')<<endl; //查找第一个子串“c”,返回下标值 cout<<s.find("c")<<endl; //查找第一个子串“cat”,返回下标值 cout<<s.find("cat")<<endl; //查找第一个子串“dog”,返回下标值 cout<<s.find("dog")<<endl; //查找第一个子串“dogc”,查不到则返回4294967295 cout<<s.find("dogc")<<endl; return 0; }
运行结果:
0 0 0 4 4294967295
2.3.11 string对象的比较
string对象可与使用compare()方法与其他字符串相比较。如果它比对方大,则返回1;如果它比对方小,则返回-1;如果它与对方相同(相等),则返回0。代码如下:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="cat dog cat"; //s比“cat”字符串大,返回1 cout<<s.compare("cat")<<endl; //s与“cat dog cat”相等,返回0 cout<<s.compare("cat dog cat")<<endl; //s比“dog”小,返回-1 cout<<s.compare("dog")<<endl; return 0; }
运行结果:
1 0 -1
2.3.12 用reverse反向排序string对象
采用reverse()方法可将string对象迭代器所指向的一段区间中的元素(字符)反向排序。reverse()方法需要声明头文件“#include <algorithm>”。代码如下:
#include <string> #include <iostream> #include <algorithm> using namespace std; int main(int argc, char * argv[]) { string s; s="123456789"; reverse(s.begin(), s.end()); cout<<s<<endl; return 0; }
运行结果:
987654321
2.3.13 string对象作为vector元素
string对象可以作为vector向量的元素,这种用法,类似于字符串数组。代码如下:
#include <vector> #include <string> #include <iostream> #include <algorithm> using namespace std; int main(int argc, char * argv[]) { vector<string> v; v.push_back("Jack"); v.push_back("Mike"); v.push_back("Tom"); cout<<v[0]<<endl; cout<<v[1]<<endl; cout<<v[2]<<endl; cout<<v[0][0]<<endl; cout<<v[1][0]<<endl; cout<<v[2].length()<<endl; return 0; }
运行结果:
Jack Mike Tom J M 3
2.3.14 string类型的数字化处理
在ACM竞赛中,常常需要将读入的数字的每位分离出来,如果采用取余的方法,花费的时间就会太长,这时候,我们可以将读入的数据当成字符串来处理,这样就方便、省时多了。下面这个程序演示了求一个整数各位的和:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; s="1234059"; int i; int sum=0; for(i=0; i<s.length(); i++) { if(s[i]=='0')sum+=0; else if(s[i]=='1')sum+=1; else if(s[i]=='2')sum+=2; else if(s[i]=='3')sum+=3; else if(s[i]=='4')sum+=4; else if(s[i]=='5')sum+=5; else if(s[i]=='6')sum+=6; else if(s[i]=='7')sum+=7; else if(s[i]=='8')sum+=8; else if(s[i]=='9')sum+=9; } cout<<sum<<endl; return 0; }
运行结果:
24
2.3.15 string对象与字符数组互操作
下面这个程序演示了字符数组与string对象的输入与输出:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s; char ss[100]; //输入字符串到字符数组中 scanf("%s", &ss); //字符数组赋值线字符串对象 s=ss; //用printf输出字符串对象,要采用c_str()方法 printf(s.c_str()); //换行 cout<<endl; //用printf输出字符数组 printf("%s", ss); //换行 cout<<endl; //用cout输出字符串对象 cout<<s<<endl; //用cout输出字符数组 cout<<ss<<endl; return 0; }
输出结果(从键盘输入“abc123”字符串后按回车键):
abc123 abc123 abc123 abc123 abc123
2.3.16 string对象与sscanf函数
在C语言中,sscanf函数很管用,它可以把一个字符串按你需要的方式分离出子串,甚至是数字。下面这个程序演示了sscanf函数的具体用法:
#include <string> #include <iostream> using namespace std; int main(int argc, char * argv[]) { string s1, s2, s3; char sa[100], sb[100], sc[100]; //将字符串分离成子串,分隔符为空格 sscanf("abc 123 pc", "%s %s %s", sa, sb, sc); s1=sa; s2=sb; s3=sc; cout<<s1<<" "<<s2<<" "<<s3<<endl; //将字符串分离成数字,分隔符为空格 //当用到数字的时候,跟scanf一样,它要传指针地址 int a, b, c; sscanf("1 2 3", "%d %d %d", &a, &b, &c); cout<<a<<" "<<b<<" "<<c<<endl; //将字符串分离成数字,分隔符为“,”和“$” //当用到数字的时候,跟scanf一样,它要传指针地址 int x, y, z; sscanf("4,5$6", "%d, %d$%d", &x, &y, &z); cout<<x<<" "<<y<<" "<<z<<endl; return 0; }
运行结果:
abc 123 pc 1 2 3 4 5 6
2.3.17 string对象与数值相互转换
有时候,string对象与数值之间需要相互转换,下面这个例子详细说明了如何完成这项工作:
#include <iostream> #include <string> #include <sstream> using namespace std; //C++方法:将数值转换为string string convertToString(double x) { ostringstream o; if (o << x) return o.str(); return "conversion error"; //if error } //C++方法:将string转换为数值 double convertFromString(const string &s) { istringstream i(s); double x; if (i >> x) return x; return 0.0; //if error } int main(int argc, char * argv[]) { //将数值转换为string的第一种方法:C方法 char b[10]; string a; sprintf(b, "%d",1975); a=b; cout<<a<<endl; //将数值转换为string的第二种方法:C++方法 string cc=convertToString(1976); cout<<cc<<endl; //将string转换为数值的方法:C++方法 string dd="2006"; int p=convertFromString(dd)+2; cout<<p<<endl; return 0; }