3.2.1定义和初始化string
初始化string对象常用的一些方式
string s1;//s1是个空字符串
string s2=s1;//s2是s1的副本
string s3=“hiya”
string s4(10,'c')//s4的内容是cccccccccc
初始化string对象的方式
string s1
string s2(s1)//s2是s1的副本
string s2=s1//等价于s2(s1),s2是s1的副本
string s3=“value”//等价于上面
string s4(n,‘c’)//把s4初始化为由连续n个字符c组成的串
直接初始化和拷贝初始化
如果使用等号(=)初始化一个变量,实际上执行的是拷贝初始化编译器把等号右侧的初始值拷贝到新建的对象中去。与之相反,如果不使用等号,则执行的是直接初始化
当初始化只有一个时,直接初始化和拷贝初始化都可以。如果像上面的s4那样初始化要用到的值是多个时一般只能使用直接初始化的方式
string s5=“hiya”
string s6(“hiya”)
string s7(10,‘c')//直接初始化,s7的内容是cccccccc
对于用多个值进行初始化的情况
要显示得创建一个(临时)对象用以拷贝
string s8=string(10,‘c');//
等于以下的语句
string temp(10,‘c’);
string s8=temp;//将temp拷贝s8
读写string对象
int main()
{
string s;
cin>>s;//将string对象读入s,遇到空白格停止
cout<<s<<endl;
return 0
这段程序首先定义一个名如s的空string,然后将标准的输入内容读取到是s中。并执行读取操作,string对象会自动忽略开头的空白,并从第一个真正的字符串开始读取,直到遇到下一个空白
如果输入的是“ hello world! ”
则输出的是“hello”,输出中间没有任何空格
string 对象的此类操作也是返回运算符左侧的运算对象做为其结果,因此,多个输入多个输出可以连在一起写:
string s1,s2;
cin>>s1>>s2;
cout<<s1<<s2<<endl;
输入的内容是“ hello world “输出的是“helloWorld”
读取未知数量的string对象
int main()
{
string word;
while(cin>>word)
cout<<word<<endl;
return 0
}
在该程序中,读取的对象是string而非int,但是while语句的条件的和之前的程序是一样的。在条件负责读取检测流的情况,如果流有效,也就是说没遇到文件结束标记或非法输入,那么执行while语句内部的操作,此时循环体将输出刚刚从标记输入读取的内容。重复若干次之后,一旦遇到文件结束的标记或者非法输入循环也就结束了
使用getline读取一行
有时我们希望能在最终得到的字符串中保留输入时的空白符,这时候应该用getline函数代替原来的原来的>>运算符。getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止,然后把所读的内容存入到那个string对象中去,getline只要一遇到换行符就结束读取操作并返回结果,哪怕输入的一开始就是换行符也是如此,如果一开始就是换行符,那么结果就是个空的string
getline也返回它的流参数,因此既然输入运算符能作为判断条件,我们也能用getline的结果作为条件
可以一次输入一整行,而不是每行输入一个词了
int main()
{
string line;
while(getline(cin,line)
cout<<line<<endl;
return 0
}
string的empty和size操作
empty函数根据string 对象是否为空返回一个对应的bool值。调用该函数的方法很简单,只要使用点操作符指明哪个对象执行了empty函数就行
while(getline(cin,line))
if(!line.empty())
cout<
string line
while(getline(cin,line))
if(line.size()>80)
cout<<line<<endl;
比较string 对象
string类定义了几种用于比较字符串的运算符。这些比较运算符逐一比较string,并且对大小写字母敏感,也就是说,在比较同一字母的大写形状和小写形式是不同的
1如果两个string对象长度不同,而且较短string对象的每个字符串都与较长string对象对应的位置上的字符相同,就说较短string对象小于较长string对象
2如果两个string对象在某些相应的位置上不一样,则string对象比较的结果其实是string对象中第一对相异字符比较的结果
下面是string对象比较的一个示例:
string str=“hello”
string phrase=“hello World”
string slang=“Hiya”
根据规则1可判断1,对象str小于对象phrase;根据规则2可判断,对象slang既大于str也大于phrase
为string对象赋值
string st1(10,‘c’),str2;
st1=st2;
两个string相加
两个string对象相加就是左侧的运算对象与右侧的运算对象串接而成,
string s1="hello,",s2="world\n"
string s3=s1+s2;
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 s7=“hello”+“,”+s2;//错误:不能把字面值相加
s4和s5初始化只用到一个加法运算符,因此很容易判断是否合法。s6的初始化形式之前没有出现过,但其实它的工作原理和连续输入输出是一样的,可以用如下的分租:
string s6=(s1+“,”)+“world”;
其中子表达式s1+“,”的结果string对象,它同时作为第二个加法运算符的左侧运算对象,因此上述语句和下面的语句是等价的
string tmp=s1+“,”;//正确:加法运算符有一个运算是string
s6=temp+“world”;//正确
s7是非法的,根据其语意加上括号就成了下面的形式:
string s7=(“hello”+“,”)+s2;//错误:不能把字面值直接相加
表3.3 cctype头文件中的函数
见课本p82
处理每个字符?使用基于范围的for语句
string str(“some string”);
for(auto c:str)
cout<
string s(“hello World”);
decltype(s.size())punct_cnt=0;
for(auto c:s)
if(ispunct(c))
++punct_cnt;
cout<<punct_cnt
<<"punctuation characters in"<<s<<endl;
使用decltype关键字声明计算变量punct_cnt,