C++处理字符串有两种方式:
(1)C风格字符串
(2)基于string类库
C风格字符串
性质:以空字符结尾,空字符被写作\0,其ASCII码是0,用来标记字符串的结尾。空字符对于C风格字符串来说特别重要。总之,就是使用char数组来定义:
char dog[8] = {'b','e','a','u','x',' ','I'','I'};
char cat[8] = {'f','a','t','e','s','s','a','\0'};
这两个都是char数组,但是只有第二个是数组是字符串。
c++中有很多处理字符串的函数,例如cout,它会逐个检查字符串中的字符,直到遇到空字符为止,如果使用cout显示cat,它就会显示前7个字符,发现空字符后停止。但是,如果是dog数组(注意它不是字符串),cout会打印出数组中的8个字符,并接着将内存中随后的各个字节解释为要打印的字符,直到遇到空字符为止(由于空字符被设置为0的字节,所以在内存中很常见),所以这一过程很快就会结束。
所以,这种方式定义字符串的方式就是要使用大量的单引号,且必须记住加上空字符。
现在有更简便的方式可以将字符数组初始化为字符串的方式——只需要一个用双引号括起来的字符串,这个字符串被称为字符串常量或者字符串字面值。
char bird[11] = "Mr. Cheeps";
char fish[] = "Bubbles";
第一行代码中隐式地包括结尾的空字符,所以不用显式的包括它,另外,各种c++输入工具通过键盘输入,将字符串读入char数组中时,将自动在结尾处加上空字符,所以应该确保数组足够大,确保可以容纳所以需要存储的字符和空字符(在确定存储字符串所需最短数组时,别忘记将结尾的空字符计算在内)。让数字比字符串长一些,没有什么坏处,只是会浪费一些空间,这是因为处理字符串的函数根据空字符的位置,而不是根据数组长度来处理,C++对字符串长度无限制。
第二行代码让编译器自己计算长度。
(1)C语言中字符串的本质:指针指向头部、固定尾部的地址相连的一段内存
(2)c语言中使用ASCII码对字符进行编码,编码后可以使用char型变量来表示一个字符。字符就是多个字符打包一起共同组成。
(3)字符串有三个核心要点:第一就是用指针指向字符串的头;第二就是固定尾部(字符串总是以
\0来结尾);第三就是组成字符串的各个字符彼此地址相连。
(4)'\0'是一个ASCII字符,其实就是编码是0的那个字符(真正的0,和数字0不一样,数字0有自己ASCII编码)(0等于'\0','0'是48).
(5)'\0'作为特殊的数字被字符串定义为结尾标志:副作用就是字符串中无法包含'\0'这个字符。(C语言中不可能有包含‘\0’字符的字符串),这种思路叫做“魔数”,正式内容不能包含“魔数”作为内容。
(6)指向字符串的指针和字符串本身是分开的两个东西:例如,char *p = "Linux";p本身就是一个字符指针,占4个字节,“Linux”分配在代码段,占6个字节。实际上是总共消耗了10个字节,这10个字节,4字节的指针p用来做指向字符串(理解为字符串的引子,本身不是字符串);5字节是真正的字符串;最后一个用来存'\0'的内存是字符串结尾表示(本身也不属于字符串)。
扩展:
字符串常量(用双引号)和字符常量(用单引号)不能弄混:
char shirt_size = 'S';
char shirt_size = "S";
第一行是对的,这里的字符常量('S')是字符串编码的简要表示。在ASCII系统中,'S'只是83的另一种写法,这个语句含义就是将83赋给shir_size。
第二行右值实际上是字符S和空字符\0的组合,它是一个字符串常量,不是字符常量,所以error
string类
要使用string类,必须在程序中包含头文件string(注意这里不包含.h),
声明格式为string 变量名;
// strtype1.cpp -- using the C++ string class
#include <iostream>
#include <string> // make string class available
int main()
{
using namespace std;
char charr1[20]; // create an empty array
char charr2[20] = "jaguar"; // create an initialized array
string str1; // create an empty string object
string str2 = "panther"; // create an initialized string
//可以使用C风格字符串来初始化string对象
cout << "Enter a kind of feline: ";
cin >> charr1;
cout << "Enter another kind of feline: ";
cin >> str1; // use cin for input
//可以使用cin来将键盘输入到存储到string对象中
cout << "Here are some felines:\n";
cout << charr1 << " " << charr2 << " "
<< str1 << " " << str2 // use cout for output
<< endl;//可以使用cout来显示string对象
cout << "The third letter in " << charr2 << " is "
<< charr2[2] << endl;
cout << "The third letter in " << str2 << " is "
<< str2[2] << endl; // use array notation
//可以使用数组表示法来访问存储在string对象中的字符
// cin.get();
// cin.get();
return 0;
}
Enter a kind of feline: ocelot
Enter another kind of feline: tiger
Here are some felines:
ocelot jaguar tiger panther
The third letter in jaguar is g
The third letter in panther is n
string和字符数组的区别主要有:
(1)可以将string对象声明为简单变量,而不是数组。
(2)类设计可以自动处理string的大小,这使得与使用数组相比,使用string对象更加方便和安全,从理论上讲,可以将char数组视为一组用于存储一个字符串的char存储单元,而string类变量时一个表示字符串的实体。