C++菜鸟学习笔记系列(7)
本期主题:标准库类型string
我们已经在前面介绍过C++中存在为我们设置好的内置类型。这些类型,比如数字和字符,体现了大多数计算机本身具备的能力。同时为了方便我们的使用,C++还为我们提供了自定义类型的方法。
除了上述之外C++语言还定义了一个内容丰富的抽象数据类型库。string 就是其中一种非常重要的标准库类型。它可以支持可变长字符串,下面作者就对其的使用进行简单介绍。
标准库类型 string表示可变长的字符序列,使用 string 类型必须先包含 string 头文件。作为标准库的一部分,string 定义在命名空间 std 中。所以在使用之前我们一般都先添加上以下代码,
#include <string> using std::string;
当然在第二行代码中我们也可以替换成:
using namespace std;
这样我们就使用了整个 std 命名空间,当然也就包含了 string 的定义了。与前述的第一种方法相比第二种方法好像看起来更加简单方便,但是它存在的缺点是命名空间 std 中包含了很多定义好的名字,如果我们不经意间使用了重复的名字则会造成始料未及的冲突。
(注意:一般来说,我们最好不要在头文件中使用 using 声明)
1.定义和初始化 string 对象
如何初始化类的对象是由类的本身所决定的。一个类可以定义很多初始化对象的方式,只不过这些方式之间有所区别,可以是初始值的数量不同或是初始值的类型不同等。
下面我们介绍一些初始化string对象的常用方式。
string s1; //s1是一个空串"" string s2 (s1); //s2是s1的副本 string s3 = s2; //s3是s2的副本,相当于s3(s3) string s4 ("hello"); //s4是字符串字面值hello的副本,是直接赋值 string s5 = "hello"; //s5是字符串字面值hello的副本,相当于 s5 ("hello"),拷贝初始化 string s6 (4,'c'); //把s6初始化为n个(这里是4) c 组成的字符串
2.string 对象上的操作
读写 string 对象
我们在C++菜鸟学习笔记系列(1)中已经介绍过通过使用标准库中的iostream来读写值。同样的,我们也可以使用IO操作符读写 string 对象:
/* Author: wxc_1998 Date: 2018/9/29 */ #include <iostream> #include <string> using namespace std; int main() { string s; cin >> s; cout << s << endl; cout << "press any key to continue!"; cin.clear(); cin.sync(); cin.get(); }
如上所示,字符串的输入输出和内置类型基本是相同的,但是我们要注意的是在使用 cin 操作时string对象会自动忽略开头的空白(空格符、换行符、制表符等)并从第一个真正的字符开始赌气,直到遇到下一处空白停止。
例如:我们输入“ 123 ”则输入的对象将是“123”。
通过上面的说明我们可以发现这样读取的字符串中是不包括空格、制标符等的,而如果我们在实际应用中却想要输入一个空格怎么办呢?这就需要用到 getline 操作了。
while (getline (cin,line)) { cout << line << endl; }
改写之后的程序遇到换行符停止,可以每次输入一整行,保留输入时的空白符。
两个string 对象相加
两个 string 对象相加得到一个新的 string 对象,其内容是把左侧的运算对象和右侧的运算对象串接而成。
/* Author: wxc_1998 Date: 2018/9/29 */ #include <iostream> #include <string> using namespace std; void main() { string s1("hello"); string s2 = "world"; string s3 = s1 + s2; cout << "s1 + s2 = " << s3 << endl; string s4 = s1 + "," + s2; //string s5 = "hello" + "," + s2; cout << "s4 is : " << s4 << endl; cout << "press any key to continue!"; cin.clear(); cin.sync(); cin.get(); }
如上代码所示,我们把s1,s2两个字符串执行相加的操作就相当于连接两个字符串,
因为标准库允许把字符字面值和字符串字面值转换为 string 对象,所以我们也可以把 string 对象和字符字面值及字符串字面值混合使用如 s4但是我们必须还要确保每个加法运算符(+)两侧的运算对象至少有一个是 string 对象。若直接相加则会出现错误,错误示例如下所示:
string s5 = "hello" + "," + s2;
(注意: C++语言中的字符串字面值并不是标准库类型 string 的对象。即字符串字面值与标准库类型 string 并不是同一种类型)
处理 string 对象中的字符
我们在学习C语言时,或者在平常的一些练习题中经常看到把一个字符串中的字符大写改成小写、判读是否出现了某个字符之类的问题。这些看起来对我们的实际使用并没有太多用处,但是存在即合理,我们在这里也简单介绍一下对 string 对象中的字符进行操作的方法。
基于范围的for语句
下面我们将介绍使用范围for语句,这种语句遍历给定序列中的每个元素,并对序列中的每个元素执行某种操作,其语法形式为:
for ( 变量: 对象序列) { 执行操作 }
来我们看一个具体示例:
/* Author: wxc_1998 Date: 2018/9/29 */ #include <iostream> #include <string> using namespace std; void main() { string s("hello world!"); int punct_count = 0; for(char c : s) { if (ispunct(c)) ++punct_count; } cout << "the number of punctuation characters is :" << punct_count << endl; cout << "press any key to continue!"; cin.clear(); cin.sync(); cin.get(); }
注意:必须要使用13年以后的编译器才可以支持C11的范围for语句。
使用下标处理一部分字符
访问 string 对象的每一个字符有两种方式,一种是使用下标,另一种则是使用迭代器(我们后续再介绍)。
下标的值称为“下标”或“索引”,任何表达式只要它的值是一个整型值就能作为索引,在所有的 string 对象中,其字符的索引值一定是在区间[ 0,string.size() )范围内。
下面我们看一个实例,实现从10进制到16进制数的转换。
/* Author: wxc_1998 Date: 2018/9/29 */ #include <iostream> #include <string> using namespace std; void main() { string s = "0123456789ABCDEF"; cout << "Enter a series of numbers between 0 and 15" << " spearated by space. Hit 'ctrl+z' when finished: " << endl; string result; unsigned int n; while (cin >> n) { if (n < s.size()) { result = result + s[n]; } } cout << "the hex number is :" << result << endl; cout << "press any key to continue!"; cin.clear(); cin.sync(); cin.get(); }
(注意:我们在输入数据结束while循环时可以输入ctrl+z)
好了这次博客就写到这里了,我们下次再见。
注:虽然这篇博客的内容十分简单,但是大家若有转载还请标明出处!
还有大家若对博客中的内容有任何问题可以随时联系我提问。