3.2.2 string对象上的操作(3)
两个string对象相加
两个string对象相加得到一个新的string对象,其内容是把左侧的运算对象与右侧的运算对象串接而成。也就是说,对string对象使用加法运算符(+)的结果是一个新的string对象,它所包含的字符由两部分组成:前半部分是加号左侧string对象所含的字符、后半部分是加号右侧string对象所含的字符。另外,复合赋值运算符(+=)(参见1.4.1节,第12页)负责把右侧string对象的内容追加到左侧string对象的后面:
- string s1 = "hello, ", s2 = "world\n";
- string s3 = s1 + s2; // s3的内容是hello, world\n
- s1 += s2; // 等价于s1s1 = s1 + s2
字面值和string对象相加
如2.1.2节(第35页)所讲的,即使一种类型并非所需,我们也可以使用它,不过前提是该种类型可以自动转换成所需的类型。因为标准库允许把字符字面值和字符串字面值(参见2.1.3节,第39页)转换成string对象,所以在需要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的初始化形式之前没有出现过,但其实它的工作机理和连续输入连续输出(参见1.2节,第7页)是一样的,可以用如下的形式分组:
- string s6 = (s1 + ", ") + "world";
其中子表达式s1 + ","的结果是一个string对象,它同时作为第二个加法运算符的左侧运算对象,因此上述语句和下面的两个语句是等价的:
- string tmp = s1 + ", "; //正确:加法运算符有一个运算对象是string
- s6 = tmp + "world"; //正确:加法运算符有一个运算对象是string
另一方面,s7的初始化是非法的,根据其语义加上括号后就成了下面的形式:
- string s7 = ("hello" + ", ") + s2; //错误:不能把字面值直接相加
很容易看到,括号内的子表达式试图把两个字符串字面值加在一起,而编译器根本没法做到这一点,所以这条语句是错误的。
因为某些历史原因,也为了与C兼容,所以C++(www.cppentry.com)语言中的字符串字面值并不是标准库类型string的对象。切记,字符串字面值与string是不同的类型。
3.2.2节练习
练习3.2:编写一段程序从标准输入中一次读入一整行,然后修改该程序使其一次读入一个词。
练习3.3:请说明string类的输入运算符和getline函数分别是如何处理空白字符的。
练习3.4:编写一段程序读入两个字符串,比较其是否相等并输出结果。如果不相等,输出较大的那个字符串。改写上述程序,比较输入的两个字符串是否等长,如果不等长,输出长度较大的那个字符串。
练习3.5:编写一段程序从标准输入中读入多个字符串并将它们连接在一起,输出连接成的大字符串。然后修改上述程序,用空格把输入的多个字符串分隔开来。