文章目录
- string对象的初始化
- string::size_type类型
- string对象的读写操作
- 使用标准库中的iostream
- 使用getline读取一整行
- string对象的比较操作
- string对象的相加操作
- 两个string对象相加
- 字面值和string对象相加
string对象的初始化
拷贝初始化(copy initialization):使用等号(=)初始化一个变量
直接初始化(direct initialization):不使用等号
当初始值只有一个时,使用两种初始化都行。如果用到的初始值有多个,一般来说只能使用直接初始化的方式:
string s5 = "hiya"; // 拷贝初始化
string s6("hiya); // 直接初始化
string s7(10, 'c'); //直接初始化
非要用拷贝初始化的方式来处理多个初始值也不是不可以,不过需要显式地创建一个(临时)对象用于拷贝:
string s8 = string(10, ' c');
等价于:
string temp(10, ' c');
string s8 = temp; // 将temp拷贝给s8
尽管初始化s8的语句合法,但和初始化s7的方式比较起来可读性较差,也没有任何补偿优势,因此不建议采用。
string::size_type类型
string::size_type类型是szie函数(例如:empty函数、size函数)返回值的类型。是一个无符号类型的值,而且足够存放下任何string对象的大小。
所有用于存放string类的size函数返回值的变量,都应该是string::size_type类型的。
由于size函数返回的是一个无符号整型数,因此如果在表达式中混用了带符号数和无符号数将可能产生意想不到的结果。例如,假设n是一个具有负值的int,则表达式s.size()<n的判断结果几乎肯定是true。因为负值n会自动地转换成一个比较大的无符号值。
PS:如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题。
string对象的读写操作
使用标准库中的iostream
执行读取操作时,string对象会自动忽略开头的空白(空格符、换行符、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止。
例如:如果程序输入:
hello world
则输出将是:
hello
输出结果中没有任何空格。
使用getline读取一整行
getline函数的参数是一个输入流和一个string对象,函数从给定的输入流中读入内容,直到遇到换行符为止(换行符也被读进来),然后把所读的内容存入到那个string对象中去(不存换行符)。
getline只要一遇到换行符就结束读取操作并返回结果,哪怕输入的一开始就是换行符也是如此。如果输入一开始就是换行符,那么所得的结果是个空string。
PS:触发getline函数返回的那个换行符实际上被丢弃掉了,得到的string对象中并不包含该换行符。
string对象的比较操作
string对象相等意味着它们的长度相同、所包含的字符也全都相同。
检验两个string对象之间关系的关系运算符都依照(大小写敏感的)字典顺序:
- 如果两个string对象的长度不同,而且较短的string对象的每个字符都与较长string对象对应位置上的字符相同,就说较短string对象小于较长string对象。
- 如果两个string对象在某些对应的位置上不一致,则string对象比较的结果其实是string对象中第一对相异字符比较的结果。
举例:
string str = "Hello";
string phrase = "Hello World";
string slang = "Hiya";
根据规则1可判断,对象str小于对象phrase;根据规则2可判断,对象slang大于phrase,那么同理也大于str。
string对象的相加操作
两个string对象相加
两个string对象相加得到一个新的string对象,其内容是把左侧的运算对象与右侧的运算对象串接而成。
string s1 = "hello,", s2 = "world\n";
string s3 = s1 + s2;
//s3的内容是hello,world\n
字面值和string对象相加
因为标准库允许将字符字面值和字符串字面值转换成string对象,所以string对象可以用这两种字面值来替代。
string s1 = "hello", s2 = "world";string s3 = s1 + "," + s2 + '\n';
当将string对象和字面值混在一条语句中使用时,必须确保每个加法运算符的两侧的对算对象至少有一个是string:
string s4 = s1 + ","; // 正确
string s5 = "hello" + ","; // 错误:两个运算对象都不是string
string s6 = s1 + "," + "world"; // 正确
string s7 = "hello" + "," + s2; // 错误
s6和s7的工作机理和连续输入连续输出是一样的,可以用如下形式分组:
string s6 = (s1 + ",") + "world";
其中子表达式s1 + ","的结果是一个string对象,同时作为第二个加法运算符的左侧运算对象,因此上述语句和下面的两个语句是等价的:
string tmp = s1 + ",";
s6 = tmp + "world";
另一方面,s7的初始化是非法的,根据其语义加上括号后就成了下面的形式:
string s7 = ("hello" + ",") + s2;
很容易看到,括号内的子表达式试图把两个字符串字面值加在一起,而编译器根本没法做到这一点,所以这条语句是错误的。
PS:因为某些历史原因,也为了与C兼容,所以C++语言中的字符串字面值并不是标准库类型string对象。切记,字符串字面值和string是不同的类型。