标准库类型string
定义和初始化string对象
如果使用等号初始化一个变量,实际上执行的是拷贝初始化,编译器把等号右侧的初始值拷贝到新创建的对象中去。与之相反,如果不使用等号,则执行的是直接初始化。
#include <string>
using std::string
string s1; // 默认初始化,s1是一个空串
string s2 = s1; // s2是s1的副本
string s3 = "hiya"; // 拷贝初始化,s3是该字符串字面值的副本
string s4(10, 'c'); // 直接初始化,s4的内容是cccccccccc
string s5("hiya"); // 直接初始化
string s6 = string(10, 'c'); // 拷贝初始化,s6的内容是cccccccccc
当初始值只有一个时,使用直接初始化或拷贝初始化都行。如果像上面的s4那样初始化要用到的值有多个,一般来说只能使用直接初始化的方式。如果非要采用拷贝初始化的方式,则需要显示地创建一个(临时)对象用于拷贝:如s6,其本质上等价于:
string temp(10, 'c'); // temp的内容是cccccccccc
string s7 = temp; // 将temp拷贝给s8
string对象上的操作
使用getline读取一整行
getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止(注意换行符也被读进来了),然后把所读的内容存入到那个string对象中去(注意不存在换行符,触发getline函数返回的那个换行符实际上被丢弃掉了,得到的string对象中并不包含该换行符)。getline只要一遇到换行符就结束读取操作并返回结果。
比较string对象
string对象比较依照(大小写敏感的)字典顺序:
- 如果两个string对象的长度不同,而且较短string对象的每个字符都与较长的string对象对应位置上的字符相同,就说明string对象小于较长string对象。
- 如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果。
// 根据规则1可判断,对象str小于对象phrase;根据规则2可判断,对象slang既大于str也大于phrase;
string str = "Hello";
string phrase = "Hello World";
string slang = "Hiya";
两个string对象相加
string s1 = "Hello, ", s2 = "world\n";
string s3 = s1 + s2;
s1 += s3; // 等价于s1 = s1 + s2
字面值和string对象相加
标准库允许把字符字面值和字符串字面值转换成string对象,所以在需要string对象的地方就可以使用这两种字面值来替代。
string s1 = "Hello, ", s2 = "world\n";
string s3 = s1 + “, ” + s2 + '\n';
当把string对象和字符字面值及字符串字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的运算对象至少有一个是string:
string s4 = s1 + ", "; // 正确:把一个string对象和一个字面值相加
string s5 = "hello" + ", "; // 错误:两个运算对象都不是string
string s6 = s1 + ", " + "world";
string s7 = "hello" + ", " + s2;
s6的初始化形式的工作机理和连续输入连续输出是一样的,可以用如下形式分组:
string s6 = (s1 + ", ") + "world";
其中子表达式s1 + ", "的结果是一个string对象,它同时作为第二个加法运算符的左侧对象,因此上述语句和下面的两个语句是等价的:
string tmp = s1 + ", ";
string s6 = tmp + "world";
s7的初始化形式是非法的,根据其语义加上括号后就成了下面的形式:
string s7 = ("hello" + ", ") + s2; // 错误:不能把字面值直接相加
切记:字符串字面值与string是不同的类型。