c++从零开始---复合类型之C-风格字符串

本文介绍了C++中处理字符串的两种方式,包括C-风格字符串和基于string类的方法。详细讲解了字符串的构成、初始化、拼接以及输入输出问题。针对cin的限制,提出了使用getline()和get()函数来读取整行字符串的方法,解决了输入问题。
摘要由CSDN通过智能技术生成

字符串是存储在内存的连续字节中的一系列字符。c++ 处理字符串的方式有两种,一种是来自 c 语言,被称为 C-风格字符串,另一种是基于 string 类库的方法。

1、字符串的构成

储存在连续字节中的一些列字符意味着可以将字符串储存在 char 数组中,其中每个字符都位于自己的数组元素中。即每一个元素代表一个字符。

比如:“i like you, how about you?”。这样的一个字符串里面有字母,标点符号和空格。而按照 ASCII 码将每一个符号进行编码得到其对应的数字,再将其储存在数组中。i 这个字符将被转换为 73,然后储存在这个元素所对应的字节中。

C-风格字符串具有一种特殊的性质:以空字符结尾,空字符被写成 \0,其 ASCII 码为 0,用来标记字符串的结尾。例如下来声明:

char a[10] = {'b','e','a','u','t','i','f','u','l'};
char b[10] = {'b','e','a','u','t','i','f','u','l','\0'};

这两个数组都是 char 数组,但只有第二个是字符串。如果使用 cout 显示 a,cout 将打印出 9 个字母,并接着将内存中随后的各个字节解释为要打印的字符,直到遇到空字符为止。如果打印 b,则将显示 9 个字母,发现空字符后停止。
注意:空字符也占数组的位数,即在声明时,所声明的数组长度应该大于或等于字符串长度+1。如上代码,beautiful 字符串只有九个字符,但是需要声明至少 10 个长度。当然也可以声明大于 10。

2、字符串初始化

使用引号括起字符串即可进行初始化,这种字符串被称为字符串常量或字符串字面值。

char a[10] = "Beautiful"
char b[] = "How beautifule a girl"

注意:用引号括起的字符串隐式地包括结尾的空字符,因此不需要显式地书写。

3、拼接字符串

任何两个由空白(空格、制表符和换行符)分隔的字符串常量都将自动拼接成一个。下列语句输出相同:

cout << "I like you" << endl;
cout << "I " "like " "you" << endl;
cout << "I "
"like "
"you" << endl;

4、字符串输入的问题

cin 使用空白(空格、制表符和换行符)来确定字符串的结束位置,意味着可能出现下列情况:
示例程序4.1:

#include <iostream>
int main()
{
	using namespace std;
	const int Size = 20;
	char name [Size];
	char dessert [Size];
	cout << "Enter your name:\n";
	cin >> name;
	cout << "Enter your favorite dessert:\n";
	cin >> dessert;
	cout << "I have some " << dessert << " for you, " << name << endl;
	return 0;
}

运行结果:
在这里插入图片描述
正常过程应该是我们输入名字 name 和甜点 dessert 之后,程序才会有输出,但是在我们输入名字后,程序直接进行了输出。实际上,cin 在处理这一段程序时的内部过程如下:
由于 cin 使用空白(空格、制表符和换行符)来确定字符串的结束位置,这意味着 cin 在获取字符数组时只能获得一个连续的单词,读取该单词后,cin 将该字符串放到数组中,并自动在结尾添加空字符。我们所输入的剩余的单词被留在了输入队列中,这里就是输入了第一个单词 wang,而 zhongxing 被留在了输入队列中。当 cin 在输入队列中搜索用户喜欢的甜点时,它发现了 zhongxing,并将它放在了 dessert 数组中。

5、读取一行字符串

因为 c++ 的 cin 具有的特性,我们想要读取整行时就不能单独使用 cin,c++ 给出了其它的方法,面向行的类成员函数:getline() 和 get()。两个函数都能读取一行输入,直到到达换行符。所不同的是,getline() 将丢弃换行符,ger() 将换行符保留在输入序列中。

5.1 getline()

使用 cin.getline()的方法调用函数。该函数有两个参数,第一个参数用来存储输入行的数组的名称,第二个参数是要读取的字符数。
注意:如果这个参数是 20,那么函数最多读取 19 个字符,余下的一个空间用于存储自动添加的空字符。
用这样的方法替换上面程序的 cin:

cin.getline(name,20);

5.2 get()

由于 get() 不舍弃换行符,那么在连续两次调用 get() 时,将出现错误:第一次调用后,换行符将留在输入队列中,第二次调用时看到的第一个字符就是换行符,因此 get() 认为已经到达行尾,而没有发现任何可读取的内容。如果不借助其它帮助,get() 将不能跨过该换行符。

如果将示例程序 1.4.1 的所有 getline() 替换成 get(),就会出现这种情况

当 get() 不带任何参数时,cin.get() 可读取下一个字符,包括换行符,因此可以用它来处理换行符,为下一次的调用做准备。

在两个 get() 之间加一个 cin.get();,将在输入队列的换行符取消,就可以解决这个问题。

注意:单独使用 cin() 时,cin 可以识别换行符并将其去掉,但是当先使用 cin(),接着使用 cin.getline() 时,该函数将得到一个换行符,因为 cin() 并未将换行符去掉,而是留在了输入队列。此时可以使用 cin.get() 将其去掉。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值