1、string的一些概念
a) string表示可变长的字符序列,使用string类型必须首先包含string头文件。作为标准库一部分,string定义在命名空间std中。比如想用string,先记得在头文件include<string>和记得string前面添加std::或者使用using namespace std;
2、定义和初始化string对象
初始化string对象的方式
string s1 ;//默认初始化 s1是一个空字符串拷贝初始化
string s2(s1);//s2 是s1的副本 直接初始化
string s2 = s1;//等价与s2(s1),s2是s1的副本拷贝初始化
string s3 (“value”);//s3是字面值“value”的副本,除了字面值最后的那个空字符外拷贝初始化
string s3 = “value”;//等价于s3(“value”),s3是字面值”value”的副本直接初始化
string s4(10,’c’);//把s4初始化为连续10个字符为c组成的串,s4的内容是cccccccccc 直接初始化
string s4 = string(10,’c’);//把s4初始化为连续10个字符为c组成的串,s4的内容是cccccccccc 直接初始化
注意:如果使用等号(=)初始化一个变量,实际上执行的是拷贝初始化,编译器会把等号右侧的初始值拷贝到新创建的对象中去。如果不使用等号,则执行的是直接初始化。
3、两个string类型字符串如何判断是否相等
第一种方法:例如:将string类型字符串转换为char*类型,再根据char*类型相关的函数来判断
std::string a("hello");
std::string b("abc");
strcmp(a.c_str(), b.c_str());
第二种方法:相等性运算符(==和!=)分别检验两个string对象相等或不相等,string对象相等意味着它们的长度相同而且所包含的字符也全都相同。关系运算符<、<=、>、>=分别检验一个string对象是否小于、小于等于、大于、大于等于另外一个string对象。上述这些运算符都依照(大小写敏感的)字典顺序:
1、如果两个string对象的长度不同,而且较短string对象的每个字符都与较长string对象对应位置上的字符相同,就说较短string对象小于较长string对象。
2、如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果。
举例:
string str = “Hello”;
string phrase = “Hello World”;
string slang = “Hiya”;
结果:对象str小于对象phrase,对象slang大于对象str也大于对象phrase
4、string的empty和size操作
empty函数根据string对象是否为空返回一个对应的布尔值。
size函数返回string对象的长度(string对象中字符的个数)。
string::size_type类型
size函数返回的就是size_type类型的值。size函数返回的是一个无符号整数型。
注意:如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题。
为string对象赋值
对于string类而言,允许把一个对象的值赋给另外一个对象
string st1(10,’c’) ,st2;//st1的内容是cccccccccc;st2是一个空字符串。
st1 = st2;//赋值:用st2的副本替换st1的内容,此时st1和st2都是空字符串。
两个string对象相加
两个string对象相加得到一个新的string对象,其内容是把左侧的运算对象与右侧的运算对象串接而成。
string s1 = “hello,”,s2 = “world\n”;
string s3 = s1 + s2;//s3的内容是hello,world\n
s1 += s2;//等价于s1 = s1 + s2;
字面值和string对象相加
string s1 = “hello”,s2 = “world”;//在s1和s2中都没有标点符号
string s3 = s1 + “,” + s2 + ’\n’;
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符(+)的两侧的运算符对象至少一个是string。
string s4 = s1 + “,”;//正确:把一个string对象和一个字面值相加
string s5 = “hello” + “,”;//错误:两个运算对象都不是string
string s6 = s1 + “,”+ “world”;//正确:每个加法运算符都有一个运算符对象是string, 加法运算从左到右开始运算,这样此表达式等价于string s6 = (s1 +“,”)+ “world”;表达式s1 +“,”的结果是一个string对象。
string s7 = “hello” + “,” + s2;//错误:不能把字面值直接相加
处理string对象中的字符
必须包含cctype头文件(include<cctype>)
isalnum(c) 当c是字母或数字时为真
isalpha(c) 当c是字母时为真
iscntrl(c) 当c是控制字符时为真
isdigit(c) 当c是数字时为真
isgraph(c) 当c不是空格但可以打印时为真
islower(c) 当c是小写字母时为真
isprint(c) 当c是可打印字符时为真(即c是空格或c具有可视形式)
ispunct(c) 当c是标点符号时为真(即c不是控制字符、数字、字母、可打印空白中的一种)
isspace(c) 当c是空白时为真(即c是空格、横向制表符、纵向制表符、回车符、换行符、进制符中一种
isupper(c) 当c是大写字母时为真
isxdigit(c) 当c是十六进制数字时为真
tolower(c) 如果c是大写字母,输出对应的小写字母,否则原样输出c
toupper(c) 如果c是小写字母,输出对应的小写字母,否则原样输出c
9、处理每个字符?使用基于范围的for语句
for(declaration :expression)
statement
1、string str(“some string”);
//每行输出str中的一个字符
for (auto c :str) //对于str中的每个字符
cout <<c <<endl; //输出当前字符,后面紧跟一个换行符
2、string s(“Hello World!!!”);
//punct_cnt的类型和s.size的返回值类型一样
decltype(s.size()) punct_cnt = 0;
//统计s中标点符号的数量
for (auto c :s) //对于s中的每个字符
if(ispunct(c)) //如果该字符是标点符号
++punct_cnt;
cout <<punct_cnt<<endl;
输出结果是3
10、使用范围for语句改变字符串中的字符
1、string str(“some string”);
//转换成大写形式
for (auto &c :str) //对于str中的每个字符
c = toupper(c);//c是一个引用,因此赋值语句将改变s中字符的值
cout <<str <<endl; //输出当前字符,后面紧跟一个换行符
输出结果为SOME STRING
只处理一部分
1、string str(“some string”);
if(!str.empty())
str[0] = toupper(str[0]);
cout <<str <<endl; //输出当前字符,后面紧跟一个换行符
程序的结果是
Some string
12、使用下标执行迭代
把str的第一个字母全部变成大写
//依次处理s中的字符直至我们处理完全部字符或者遇到一个空白
for(decltype(s.size()) index = 0;
index != s.size() && !isspace(s[index]);++index)
s[index] = toupper(s[index]);//将当前字符改成大写形式
程序结果为
SOME string
13、构造string的其他方法
//n、len2和pos2都是无符号值
const char* cp = “Hello World!!!”;
char noNull[] = {‘H’,’i’};
string s1(cp);//拷贝cp中的字符直到遇到空字符;s1 ==“Hello World!!!”(当我们从一个const char*创建string时,指针指向的数组必须以空字符结尾,拷贝操作遇到空字符时停止)
(如我们还传递给构造函数一个计数值,数组就不必以空字符结尾,1中string s2(noNull,2);就是这种情况,
如果我们未传递计数值且数组也未以空字符结尾,或者给定计数值大于数组大小,则构造函数的行为是未定义的比如:strigng s3(noNull);//未定义:noNull不是以空字符结束)
1、string s(cp,n) s是cp指向的数组中前n个字符的拷贝。此数组至少应该包含n个字符。
string s2(noNull,2);//从noNull拷贝两个字符:s2 ==“Hi”;
string s4(cp+6,5);//从cp[6]开始拷贝5个字符;s4 == “World”’;
2、string s(s2,pos2) s是string s2从下标pos2开始的字符的拷贝。若pos2 > s2.size(),构造函数的行为未定义
string s6(s1,6); //从s1[6]开始拷贝,直至s1末尾;s6 == “World!!!”;
string s8(s1,16); //抛出一个out_of_range异常
3、string s(s2,pos2,len2) s是string s2从下标pos2开始len2个字符的拷贝。若pos2 > s2.size(),构造函数的行为未定义,不管len2的值是多少,构造函数至多拷贝s2.size()-pos2个字符。
string s5(s1,6,5);//从s1[6]开始拷贝5个字符;s5 = “World”;
string s7(s1,6,20);//正确,只拷贝到s1末尾;s7 ==“World!!!”;
14、substr操作
substr操作返回一个string,它是原始string的一部分或全部的拷贝。可以传递给substr一个可选的开始位置和计数值。
string s(“hello world”);
s.substr(pos) 从s中pos位置开始截取到末尾的字符串,如果开始位置超过了string的大小,则substr函数抛出一个out_of_range异常
string s3 = s.substr(6); //s3 = world
string s5 = s.substr(12); //抛出一个out_of_range异常
s.substr(pos,n) 返回一个string,包含s中从pos开始的n个字符的拷贝。pos的默认值为0、n的默认值为s.size() - pos,即拷贝从pos开始的所有字符。如果开始位置加上计数值大于string的大小,则substr会调用整计数值,只拷贝到string的末尾
string s2 = s.substr(0,5);// s2 = hello
15、insert、erase、assign、append、replace函数
args可以是下列形式之一:append和assign可以使用所有的形式。
str不能与s相同,迭代器b和e不能指向s。
str 字符串str
str,pos,len str中pos开始最多len个字
cp,len 从cp指向的字符数组的前(最多)len个字符
cp cp指向的以空字符结尾的字符数组
n,c n个字符c
b,e 迭代器b和e指定的范围内的字符
初始化列表 花括号包围的,以逗号分隔的字符列表
s.insert(pos,args) 在pos之前插入args指定的字符。pos可以是一个下标或一个迭代器。接受下标的版本返回一个指向s的引用;接受迭代器的版本返回指向第一个插入字符的迭代器。
string s = “some string”,s2 = “some other strimg”;
s.insert(0,s2);//在s中位置0之前插入s2的拷贝
//在s[0]之前插入s2中s2[0]开始的s2.size()个字符
s.insert(0,s2,0,s2.size());
const char* cp = “Stately,plump Buck”;
s.assign(cp,7);// s == “Stately”
s.insert(s.size(),cp + 7); //s == “Stately,plump Buck”
s.earse(pos,len) 删除从位置pos开始的len个字符。如果len被省略,则删除从pos开始直至s末尾的所有的字符。返回一个指向s的引用
s.earse(s.size() - 5,5)
s.assign(args) 将s中的字符替换为args指定的字符。返回一个指向s的引用
s.assign(cp,7);// s == “Stately”
s.append(args) 将args追加到s。返回一个指向s的引用
string s(“C++ Primer”),s2 = s;//将s和s2初始化为“C++ Primer”
s.insert(s.size(),” 4th Ed.”);//s == “C++ Primer 4th Ed.”
s2.append(“ 4th Ed.”)//等价方法:将“4th Ed.”追加到s2;s == s2;
s.replace(range,args) 删除s中范围range内的字符,替换为args指定的字符。range或者是一个下标和一个长度,或者是一对指向s的迭代器。返回一个指向s的引用
replace操作是调用erase和insert的一种简写形式
//将“4th”替换为“5th”的等价方法
s.earse(11,3) ; //s == “C++ Primer Ed.”
s.insert(11,”5th”); //s == “C++ Primer 5th Ed.”
//从位置11开始,删除3个字符并插入”5th”
s2.replace(11,3,”5th”);//等价方法:s == s2
assign和append函数无须指定要替换string中哪个部分。assign总是替换string中的所有内容,append总是将新字符追加到string末尾。
string搜索操作
string类提供了6个不同的搜索函数,每个函数都有4个重载版本。每个搜索操作都返回一个string::size_type值,表示匹配发生位置的下标。如果搜索失败,则返回一个名为string::npos的static成员。标准库将npos定义为一个const string::size_type类型,并初始化为值-1.由于npos是一个unsigned类型,此初始值意味着npos等于任何string最大的可能大小。
注意:string搜索函数返回string::size_type值,该类型是一个unsigned类型。因此,用一个int或其他带符号类型来保存这些函数的返回值不是一个好主意。
string name(“AnnaBelle”);
auto pos1 = name.find(“Anna”);//pos1 == 0
pos1 = name.find(“anna”);//pos1 == npos
查找参数指定的字符串,若找到,则返回第一个匹配位置的下标,否则返回npos
string numbers(“0123456789”),name(“r2d2”);
auto pos = name.find_first_of(numbers);//返回1,即,name中第一个数字的下标
查找与给定字符串中任何一个字符匹配的位置。
string dept(“03714p3”);//返回5-字符‘p’的下标
auto pos = dept.find_find_first_not_of(numbers);
搜索第一个不在参数中的字符
args 必须是以下形式之一
c,pos 从s中位置pos开始查找字符c.pos默认为0
s2,pos 从s中位置pos开始查找字符串s2.pos默认为0
cp,pos 从s中位置pos开始查找指针cp指向的以空字符结尾的C风格字符串。pos默认为0
cp,pos,n 从s中位置pos开始查找指针cp指向的数组的前n个字符。pos和n无默认值
//搜索操作返回指定字符出现的下标,如果未找到则返回npos
s.find(args) //查找s中args第一次出现的位置
s.rfind(args) //查找s中args最后一次出现的位置
s.find_first_of(args) //在s中查找args中任何一个字符第一次出现的位置
s.find_first_of(args) //在s中查找args中任何一个字符最后一次出现的位置
s.find_first_not_of(args) 在s中查找第一个不在args中的字符
s.find_last_not_of(args) 在s中查找最后一个不在args中的字符
string river(“Mississippi”);
auto first_pos = river.find(“is”);//返回1
auto last_pos = river.rfind(“is”);//返回4
compare函数
compare返回0、正数、负数
s2 比较s和s2
pos1,n1,s2 将s中从pos1开始的n1个字符与s2进行比较
pos1,n1,s2,pos2,n2 将s中从pos1开始的n1个字符与s2中从pos2中开始的n2个字符进行比较
cp 比较s与cp指向的以空字符结尾的字符数组
pos1,n1,cp 将s中从pos1开始的n1个字符与cp指向的以空字符结尾的字符数组进行比较
pos1 ,n1,cp,n2 将s中从pos1开始n1个字符与指针cp指向的地址开始的n2个字符进行比较
数组转换
string和数值之间的转换
to_string(val) 一组重载函数,返回数值val的string表示。val任何算术类型。对每个浮点类型和int或更大的整型,都有相应版本的to_string。与往常一样,小整型会被提升。
int i = 42;
string s = to_string(i);//将整型i转换为字符表达式
double d= stod(s);//将字符串s转换为浮点数
stoi(s,p,b) 返回s的起始子串(s,p,b) 返回s的起始子串(表示整数内容)的数值,返回值类型分别为int、long、unsigned、unsigned long、long long、unsigned long long。b表示转换所用的基数,默认值为10。p是size_t指针,用来保存s中第一个非数值字符的下标,p默认为0,即,函数不保存下标
stol(s,p,b)、stoul(s,p,b)、stoll(s,p,b)、stoull(s,p,b)
stof(s,p) 返回s的起始子串(表示浮点内容)的数值,返回值类型分别是float、double或long double。参数p的作用与整数转换函数中一样
stod(s,p) stold(s,p);