3.2.2 string对象上的操作(2)
因为line中不包含换行符,所以我们手动地加上换行操作符。和往常一样,使用endl结束当前行并刷新显示缓冲区。
触发getline函数返回的那个换行符实际上被丢弃掉了,得到的string对象中并不包含该换行符。
string的empty和size操作
顾名思义,empty函数根据string对象是否为空返回一个对应的布尔值(参见第2.1节,32页)。和Sales_item类(参见1.5.2节,第23页)的isbn成员一样,empty也是string的一个成员函数。调用该函数的方法很简单,只要使用点操作符指明是哪个对象执行了empty函数就可以了。
通过改写之前的程序,可以做到只输出非空的行:
- // 每次读入一整行,遇到空行直接跳过
- while (getline(cin, line))
- if (!line.empty())
- cout << line << endl;
在上面的程序中,if语句的条件部分使用了逻辑非运算符(!),它返回与其运算对象相反的结果。此例中,如果str不为空则返回真。
size函数返回string对象的长度(即string对象中字符的个数),可以使用size函数只输出长度超过80个字符的行:
- string line;
- // 每次读入一整行,输出其中超过80个字符的行
- while (getline(cin, line))
- if (line.size() > 80)
- cout << line << endl;
string::size_type类型
对于size函数来说,返回一个int或者如前面2.1.1节(第34页)所述的那样返回一个unsigned似乎都是合情合理的。但其实size函数返回的是一个string::size_type类型的值,下面就对这种新的类型稍作解释。
string类及其他大多数标准库类型都定义了几种配套的类型。这些配套类型体现了标准库类型与机器无关的特性,类型size_type即是其中的一种。在具体使用的时候,通过作用域操作符来表明名字size_type是在类string中定义的。
尽管我们不太清楚string::size_type类型的细节,但有一点是肯定的:它是一个无符号类型的值(参见2.1.1节,第32页)而且能足够存放下任何string对象的大小。所有用于存放string类的size函数返回值的变量,都应该是string::size_type类型的。
过去,string::size_type这种类型有点儿神秘,不太容易理解和使用。在C++(www.cppentry.com)11新标准中,允许编译器通过auto或者decltype(参见2.5.2节,第68页)来推断变量的类型:
- auto len = line.size(); // len的类型是string::size_type
由于size函数返回的是一个无符号整型数,因此切记,如果在表达式中混用了带符号数和无符号数将可能产生意想不到的结果(参见2.1.2节,第36页)。例如,假设n是一个具有负值的int,则表达式s.size()<n的判断结果几乎肯定是true。这是因为负值n会自动地转换成一个比较大的无符号值。
如果一条表达式中已经有了size()函数就不要再使用int了,这样可以避免混用int和unsigned可能带来的问题。
比较string对象
string类定义了几种用于比较字符串的运算符。这些比较运算符逐一比较string对象中的字符,并且对大小写敏感,也就是说,在比较时同一个字母的大写形式和小写形式是不同的。
相等性运算符(==和!=)分别检验两个string对象相等或不相等,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可判断,对象str小于对象phrase;根据规则2可判断,对象slang既大于str也大于phrase。
为string对象赋值
一般来说,在设计标准库类型时都力求在易用性上向内置类型看齐,因此大多数库类型都支持赋值操作。对于string类而言,允许把一个对象的值赋给另外一个对象:
- string st1(10, 'c'), st2; // st1的内容是 cccccccccc;st2是一个空字符串
- st1 = st2; // 赋值:用st2的副本替换st1的内容
- // 此时st1和st2都是空字符串