使用字符数组来存储字符串,其实是C的做法,C++除了沿用这样的做法外,还引入了专门的数据类型string来处理字符串。string本质是类,所以有很多字符串处理方法。
因为string是C++中的类,而类是C++的高级用法,所以本节的内容有一定的难度,如果不能较好地理解,可以尝试先记忆介绍的使用方法。
一、C++中的string类型
C++中有专门的string类型来处理字符串,所以可以像int、double这些基本数据类型一样很简单地使用string类型存储字符串,使用string最好引入string头文件:
#include<iostream> #include<string> using namespace std; int main() { string s; cin>>s; cout<<s<<endl; return 0; }
需要特别注意的是,通过 cin 输入 string,与 cin 输入数字相同,默认的分割符号是空格、回车、制表符,所以上面的程序如果输入Hello World
,字符串 s 的结果是Hello
,只会把空格前的内容输入到字符串 s 中。如果想将有空格的内容全部输入到字符串中,可以使用 getline(cin,s);
,这样可以将一整行的内容输入到字符串中 。
二、使用string中的某个字符
可以像使用数组下标访问数组元素那样通过下标来使用string中的某个字符,不仅仅是取出来使用,甚至可以修改:
#include<iostream> #include<string> using namespace std; int main() { string s = "Hello"; cout<<s<<endl; cout<<s[0]<<s[1]<<s[2]<<s[3]<<s[4]<<endl; s[0] = 'X'; cout<<s<<endl; return 0; }
三、string与字符数组字符串的相互转换
C使用字符数组来存储字符串,C++除沿用这样的方法外,还有专门的string类型来处理字符串。可以通过代码来相互转换:
#include<iostream> #include<cstring> #include<string> using namespace std; int main() { char str[15] = "Hello World"; string s(str); //使用字符数组初始化string cout<<s<<endl; s = "Hi"; //s.c_str()方法返回string变量s的字符数组存储形式 //再通过strcpy函数拷贝到str数组中 strcpy(str,s.c_str()); cout<<str<<endl; return 0; }
四、string常用方法
1.string相比较char数组存储字符串的优势
string可以认为是一种数据类型,支持string变量直接赋值成另一个变量:
#include<iostream> #include<string> using namespace std; int main() { string s = "Hello"; string ss = s; cout<<ss; return 0; }
string类型支持+运算,表示字符串拼接:
#include<iostream> #include<string> using namespace std; int main() { string s = "Hello"; cout<<s+" World"<<endl; s += " World"; cout<<s<<endl; return 0; }
string类型支持>、>=、<、<=、==、!=这些比较运算,string字符串比较时规则和char数组存储的字符串规则一致:
#include<iostream> #include<string> using namespace std; int main() { string s; cin>>s; if(s=="yes") cout<<"you inputed YES"; return 0; }
2.string的初始化
string本质是类,有丰富的构造函数(后面会有所介绍),所以初始化string变量的方式很多:
#include<iostream> #include<string> using namespace std; int main() { string s1 = "Hello"; //通过赋值语句初始化 cout<<s1<<endl; string s2("Hello"); //用字符串常量初始化 cout<<s2<<endl; string s3(s2); //用其它字符串变量初始化 cout<<s3<<endl; char str[6] = "Hello"; string s4(str); //用存储在字符数组的字符串初始化 cout<<s4<<endl; return 0; }
3.string字符串长度
使用string的length方法或者size方法都能获取字符串的长度。使用方法参见下面的程序:
#include<iostream> #include<string> using namespace std; int main() { string s; cin>>s; cout<<s.length()<<endl; //使用length方法获取字符串长度 cout<<s.size()<<endl; //使用size方法获取字符串长度 //与string长度相关的变量可以使用int类型,但推荐使用size_t或者string::size_type size_t n = s.length(); //使用size_t类型变量存储获取到的字符串长度 //使用size_t类型控制变量遍历string的每个字符 for(size_t i = 0;i<n;i++){ cout<<s[i]; } return 0; }
4.遍历string所有元素
可以使用for循环来依次枚举string元素的下标,实现正向以及逆向遍历string的元素:
#include<iostream> #include<string> using namespace std; int main(){ string s; cin>>s; //size_t 在标准Linux环境下本质上是 unsigned long long(无符号长整型) //正向遍历 for(size_t i = 0;i<s.length();i++) cout<<s[i]; cout<<endl; //反向遍历:控制变量是size_t类型,这里循环条件不能用 i>=0 //原因是当size_t类型变量i值为0时,执行i--后,i值会变成很大的一个整数(string::npos) //所以这里条件用 i!=string::npos for(size_t i = s.length()-1;i!=string::npos;i--) cout<<s[i]; cout<<endl; return 0; }
还可以使用STL(标准模版库)中的迭代器实现string元素的遍历(后续进阶学习内容):
#include<iostream> #include<string> using namespace std; int main(){ string s; cin>>s; //正向遍历 string::iterator it = s.begin(); for(;it != s.end();it++) cout<<*it; cout<<endl; //反向遍历 string::reverse_iterator rit = s.rbegin(); for(;rit != s.rend();rit++) cout<<*rit; cout<<endl; return 0; }
*5.修改string内容
可以通过多种语句或者调用方法修改string的内容:
#include<iostream> #include<string> using namespace std; int main () { string s = "Hello World"; cout<<1<<":"<<s<<endl; //通过下标方式修改字符串某个字符,字符串也会变化 s[5] = '+'; cout<<2<<":"<<s<<endl; //assign方法重新赋值,效果与 s="Nice to meet you";一致,但执行方式不同 s.assign("Nice to meet you"); cout<<3<<":"<<s<<endl; string st="Hello"; //swap方法交换s与st的值 s.swap(st); cout<<4<<":"<<s<<" "<<st<<endl; //append方法末尾追加字符串 //效果与 s = s+" World";或者 s+=" World";一致,但执行方式不同 s.append(" World"); cout<<5<<":"<<s<<endl; //push_back方法在字符串末尾追加字符 s.push_back('!'); cout<<6<<":"<<s<<endl; //insert方法在字符串中插入字符串 //在第0个字符前插入字符串 s.insert(0,"Say "); cout<<7<<":"<<s<<endl; //replace方法替换字符串指定区间的内容 //s从第4个开始的一共5个字符被替换成"Hi" s.replace(4,5,"Hi"); cout<<8<<":"<<s<<endl; //s从第0个开始的一共4个字符被替换成"",实现的是删除的效果 s.replace(0,4,""); cout<<9<<":"<<s<<endl; //erase方法删除字符串指定区间的所有字符 //从第2个字符开始总共删除6个字符 s.erase(2,6); cout<<10<<":"<<s<<endl; //clear方法清空字符串,变成空字符串"" s.clear(); cout<<11<<":"<<s<<endl; cout<<12<<":"<<s.size()<<endl; return 0; }
程序运行结果如下:
1:Hello World 2:Hello+World 3:Nice to meet you 4:Hello Nice to meet you 5:Hello World 6:Hello World! 7:Say Hello World! 8:Say Hi World! 9:Hi World! 10:Hi! 11: 12:0
*6.字符串查找方法
string有丰富的字符串查找方法,包括find、rfind、find_first_of、find_last_of、find_first_not_of、find_last_not_of等方法可以实现丰富的查找:
#include<iostream> #include<string> using namespace std; int main () { string s = "Hello World"; //在s中查找字符'o'的位置 cout<<1<<":"<<s.find('o')<<endl; //在s中从第5个字符开始查找字符'o'的位置 cout<<2<<":"<<s.find('o',5)<<endl; //在s中查找字符串"or"出现的位置 cout<<3<<":"<<s.find("or")<<endl; //在s中从第8个字符查找字符串"or"出现的位置,查不到返回string::npos cout<<4<<":"<<s.find("or",8)<<endl; if(s.find("or",8)==string::npos) cout<<5<<":"<<"Not found"<<endl; //在s中逆向查找字符'o'的位置 cout<<6<<":"<<s.rfind('o')<<endl; //在s中从第5个字符开始,逆向查找字符'o'的位置 cout<<7<<":"<<s.rfind('o',5)<<endl; //在s中逆向查找字符串"or"出现的位置 cout<<8<<":"<<s.rfind("or")<<endl; return 0; }
程序运行结果如下:
1:4 2:7 3:7 4:4294967295 5:Not found 6:7 7:4 8:7
#include<iostream> #include<string> using namespace std; int main () { string str("This is one string for example"); //str中第一个字符'i'出现的位置 cout<<1<<":"<<str.find_first_of('i')<<endl; //str中从第3个字符开始,第一个'i'出现的位置 cout<<2<<":"<<str.find_first_of('i',3)<<endl; //字符串"oiehtT"任意一个字符在str中第一次出现的位置 cout<<3<<":"<<str.find_first_of("oiehtT")<<endl; //从第3个字符开始,字符串"oiehtT"任意一个字符在str中第一次出现的位置 cout<<4<<":"<<str.find_first_of("oiehtT",3)<<endl; //逆向查找:str中第一个字符'e'出现的位置 cout<<5<<":"<<str.find_last_of('e')<<endl; //逆向查找:字符串"le"中任意一个字符在str中第一次出现的位置 cout<<6<<":"<<str.find_last_of("le")<<endl; return 0; }
程序运行结果如下:
1:2 2:5 3:0 4:5 5:29 6:29
#include<iostream> #include<string> using namespace std; int main () { string str = "iiiiekpkiiieylmnqqqqq"; //str中第一个不是'i'的字符的位置 cout<<1<<":"<<str.find_first_not_of('i')<<endl; //str中第一个不是"eik"字符串中任意字符的位置 cout<<2<<":"<<str.find_first_not_of("eik")<<endl; //str中从第7个字符开始查找第一个不是"eik"字符串中任意字符的位置 cout<<3<<":"<<str.find_first_not_of("eik",7)<<endl; //逆向查找:str中第一个不是字符'q'的字符出现的位置 cout<<4<<":"<<str.find_last_not_of('q')<<endl; //逆向查找:str中第一个不是字符串"nqm"的任意字符出现的位置 cout<<5<<":"<<str.find_last_not_of("nqm")<<endl; return 0; }
程序运行结果如下:
1:4 2:6 3:12 4:15 5:13
*7.获取字符串子串
可以通过string的substr方法获取字符串的子串(连续的一部分)
#include<iostream> #include<string> using namespace std; int main() { string s = "Hello World"; cout<<s<<endl; //从s下标2开始直到结尾的子串 string s1 = s.substr(2); //结果是:llo World cout<<s1<<endl; //从s下标2开始,长度为5的子串 string s2 = s.substr(2,5); //结果是:llo W cout<<s2<<endl; //从s下标0开始直到结尾的子串 string s3 = s.substr(0); //结果是:Hello World cout<<s3<<endl; return 0; }