string类型支持长度可变的字符串,C++标准库负责管理存储字符的相关内存,以及提供各种有用的操作。标准库string类型的目的就是满足对字符串的一般应用。
与其它的标准库类型一样,用户程序要使用string类型对象,必须包含相关头文件。如果程序员提供合适的using声明,那么编写出来的程序将会变得简短一些:
#include <string>
using std::string;
3.2.1 定义和初始化String对象
string标准库支持几个构造函数(2.2.3节)。构造函数是一个特殊成员函数,定义如何初始化该类型的对象。表3-1列出了几个string类型常用的构造函数。当没有明确指定对象初始代式时,系统将使用默认构造函数(2.3.4节)。
表3-1 几种初始化String对象的方式
string s1; | 默认构造函数,s1为空串 |
string s2(s1); | 将s2初始化为s1的一个副本 |
string s3("value"); | 将s3初始化为一个字符串字面值副本 |
string s4(n, 'c'); | 将s4初始化为字符'c'的n个副本 |
警告:标准库string类型和字符串字面值
因为历史原因以及为了与C语言兼容,字符串字面值与标准库string类型不是同一种类型。这一点很容易引起混乱,编程时一定要注意区分字符串字面值和string数据类型的使用,这很重要。
习题
习题3.2 什么是默认构造函数?
习题3.3 列举出三种初始化String对象的方法。
习题3.4 s和s2的值分别是什么?
string s;
int main() {
string s2;
}
3.2.2 String的读写
我们已在第1章学习了用iostream标准库来读写内置类型的值,如int,double等。同样地,也可以用iostream和string标准库,使用标准输入输出操作符来读写string对象:
// Note: #include and using declarations must be added to compile this code
int main()
{
string s; // empty string
cin >> s; // read whitespace-separated string into s
cout << s << endl; // write s to the output
return 0;
}
以上程序首先定义命名为s的字符串,第二行代码:
cin >> s; // read whitespace-separated string into s
从标准输入读取string,并将读入的串存储在s中。string类型的输入操作符:
● 读取并忽略开头所有的空白字符(如空格,换行符,制表符)。
● 读取字符直至再次遇到空白字符,读取终止。
因此,如果输入到程序的是“ Hello World! ”(注意到开头和结尾的空格),则屏幕上将输出“Hello”,而不含任何空格。
输入和输出操作的行为与内置类型操作符基本类似。尤其是,这些操作符返回左操作数作为运算结果。因此,我们可以把多个读操作或多个写操作放在一起:
string s1, s2;
cin >> s1 >> s2; // read first input into s1, second into s2
cout << s1 << s2 << endl; // write both strings
如果给定和上一个程序同样的输入,则输出的结果将是:
HelloWorld!
对于上例,编译时必须加上#include来标示iostream和string标准库,以及给出用到的所有标准库中的名字(如string,cin,cout,endl)的using声明。
从本例开始的程序均假设程序中所有必须的#include和using声明已给出。
1. 读入未知数目的string对象
和内置类型的输入操作符一样,string的输入操作符也会返回所读的数据流。因此,可以把输入操作作为判断条件,这与我们在1.4.4节读取整型数据的程序做法是一样的。下面的程序将从标准输入读取一组string对象,然后在标准输出上逐行输出:
int main()
{
string word;
// read until end-of-file, writing each word to a new line
while (cin >> word)
cout << word << endl;
return 0;
}
上例中,用输入操作符来读取string对象。该操作符返回所读的istream对象,并在读取结束后,作为while的判断条件。如果输入流是有效的,即还没到达文件尾且没遇到无效输入,则执行while循环体,并将读取到的字符串输出到标准输出。如果到达了文件尾,则跳出while循环。
2. 用getline读取整行文本
另外还有一个有用的string IO操作:getline。这个函数接受两个参数:一个输入流对象和一个string对象。getline函数从输入流的下一行读取,并保存读取的内容到string中,但不包括换行符。和输入操作符不一样的是,getline并不忽略行开头的换行符。只要getline遇到换行符,即便它是输入的第一个字符,getline也将停止读入并返回。如果第一个字符就是换行符,则string参数将被置为空string。
getline函数将istream参数作为返回值,和输入操作符一样也把它用作判断条件。例如,重写前面那段程序,把每行输出一个单词改为每次输出一行文本:
int main()
{
string line;
// read line at time until end-of-file
while (getline(cin, line))
cout << line << endl;
return 0;
}
由于line不含换行符,若要逐行输出需要自行添加。照常,我们用endl来输出一个换行符并刷新输出缓冲区。
注意由于getline函数返回时丢弃换行符,换行符将不会存储在string对象中。
习题
习题3.5 编写程序实现从标准输入每次读入一行文本。然后改写程序,每次读入一个单词。
习题3.6 解释string类型的输入操作符和getline函数分别如何处理空白字符。
3.2.3 string对象的操作
表3-2列出了常用的string操作。
表3-2 string操作
s.empty() s.size() s[n] s1 + s2 s1 = s2 v1 == v2 !=, <, <=, > 和 >= | 如果s为空串,则返回true,否则返回false。 返回s中字符的个数。 返回s中位置为n的字符,位置从0开始计数。 把s1和s2连接成一个新字符串,返回新生成的字符串。 字符串长度超出把s1内容替换为s2的副本。 比较v1与v2的内容,相等则返回true,否则返回false。 保持这些运算符惯有的含义。 |
1. string的size和empty操作
string对象的长度指的是string对象中字符的个数,可以通过size操作获取:
int main()
{
string st("The expense of spirit\n");
cout << "The size of " << st << "is " << st.size()
<< " characters, including the newline" << endl;
return 0;
}
编译并运行这个程序,得到的结果为:
The size of The expense of spirit
is 22 characters, including the newline
了解string对象是否为空是有用的。一种方法是将size与0进行比较:
if (st.size() == 0)
// ok: empty
本例中,程序员并不需要知道string对象中有多少个字符,只想知道size是否为0。用string的成员函数empty()可以更直接地回答这个问题:
if (st.empty())
// ok: empty
empty()成员函数将返回bool值(2.1节),如果string对象为空则返回true,否则返回false。
2. string::size_type类型
从逻辑上来讲,size()成员函数似乎应该返回整型数值,或如2.2节“建议”中所述的无符号整
数。但事实上,size操作返回的是string::size_type类型的值。我们需要对这种类型做一些解释。
string类类型和许多其他库类型都定义了一些伙伴类型(companion types)。这些伙伴类型使得库类型的使用是机器无关的(machine-independent)。size_type就是这些伙伴类型中的一种。它定义为与unsigned型(unsigned int或unsigned long)具有相同的含义,而且可以保证足够大可存储任意string对象的长度。为了使用由string类型定义的size_type类型,程序员必须加上作用域操作符来说明所使用的size_type类型是由string类定义的。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论