C++学习日记(12)—— 字符串

愉快的周末过后恢复更新

这节讲字符串


字符串是存储在内存的连续字节的一系列字符

提供了一种存储文本信息的快捷方式

C++处理字符串的方式有两种

一种来自C,通常就叫C风格字符串

一种是基于string类的方法

C风格字符串

char a[4]={‘a’,’b’,’c’,’d’};  不是字符串

char a[4]={‘a’,’b’,’c’,’\0′};  C风格字符串

C风格字符串有一种特殊的性质

就是以空字符\0结尾,空字符的ascll码同样为0

空字符对C风格字符串很重要

因为很多处理字符串的函数都是检测到\0才停止的

如果你用cout输出第一个数组,打印到d的时候不会停下

而是直到检测到某个不知道的内存位置的\0才会结束

对于第二个数组来说,其实你不必每个字母都用单引号

你只要像这样用一个双引号括起来就行了

char a[4]={“abc”};

这种字符串被称为字符串常量或者字符串字面值

双引号括起来后的空字符被隐藏起来了

但是仍然占了一个位置,所以要注意要算进去

一定要确保数组足够大,不然会出现下标越界的情况

一个小小的误区

字符串常量和字符常量是不一样的

一个使用双引号一个使用单引号

你可以把字符常量S赋值给变量

因为在ascll系统里字符常量S就是83

所以char a=’s’;没啥毛病

char a=”s”;就出事了

s在这里表示的是s和\0组成的字符串

“s”实际上是字符串所在的内存地址

地址是不能赋值给变量的(指针会提到地址的问题)


拼接字符串常量

还记得讲到cout的时候提到的一个无聊的点吗

  • cout<<“Hello”<<“world!”<<endl;

输出结果:Helloworld!

  • cout<<“Hello”;
  • cout<<“world!”;

输出结果:Helloworld!

  • cout<<“Hello”;
  •         <<“world!”;

输出结果:Helloworld!

事实上,任何两个由空白(空格、制表符、换行符)分隔的字符串

都将自动拼接成一个

这就是为啥上面的语句都是等价的

对于拼接的字符串来说,第一个字符串的\0被第二个字符串的首字符取代

以此类推


在数组中使用字符串(赋值和输出)

两种方法

一种就是刚刚演示的,在初始化的时候就顺手赋值了

另一种则是利用cin一个一个放进去

这个方法有一个缺陷

因为cin是使用(空白、制表符和换行符)来确定字符串的结束位置

所以cin一次就只能读取一个单词了

标准头文件cstring提供了很多和字符串相关的函数声明

前面我们讲到sizeof,说它返回的是数组的长度

所以空字符也是算的

而cstring里的strlen()比较特别

它返回的是数组中的字符串的长度

而且计算的是可见的字符,所以空字符不包含在内


面向行的输入getline()

getline函数读取整行(iostream头文件里)

它使用通过回车键输入的换行符来确定输入结尾

在存储字符串的时候就用空字符来替换换行符

要调用这种方法可以使用cin.getline()

例如

假设使用getline把姓名读入到一个包含20个元素的name数组中

可以这么写cin.getline(name,20);

注意,这里最多只能输入19个字符

面向行的输入get()

get()跟getline()类似

但是get()不会替换换行符

而是把它留在输入队伍里

那连续调用的话就会出问题了

但是还有一种变体

不带任何参数的cin.get()可以读取下一个字符

即便这个字符是换行符

cin.get(name,arsize);

cin.get();

cin.get(dessert,arsize);

这样的写法就是ok的

你还可以直接连起来

cin.getline(name,arsize).get()

总之getline()用起来简单一些

get()使得检查错误更简单一些

空行和其他问题

当这两个函数读取到一个空的行会有啥情况

get()(getline不会)会直接停止使用,下面再使用get()就没反应了

除非输入cin.clear();来恢复输入

读到的字符超过指定数目也会一样


下一节讲讲string

发表评论

您的电子邮箱地址不会被公开。