0%

C++PrimerPlus_4.2字符串

1. 4.2 字符串

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

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

  1. 来自C语言,常被称为C-风格字符串(C-sytle string)

  2. 给予string类库的方法

1.1. 字符串常量

C-风格字符串具有一种特殊的性质:以空字符(null character)结尾,空字符被写作\0,其ASCII码为0,用来标记字符串的结尾。

🍑 例子:

1
2
char dog[8] = {'b','e','a','u','x','x',' ','I','I'}; // 不是string字符串
char cat[8] = {'b','e','a','u','x','x',' ','I','\0'}; // a string! 是字符串哦耶

这两个都是char,但只有第二个数组是字符串(因为有\0空字符)。

有一种比cat写法更好的将字符数组初始化为字符串的方法,用引号“”即可。

这种字符串被称为字符串常量string constant(字符串常量)或string literal(字符串面值);

1
2
char bird[11] = "Mr.Cheeps"; // the \0 is understood
char fish[] = "Bubbles"; // let the compiler count 让字符串计算
  • 由引号括起来的字符串隐式地包括结尾的空字符,因此不显式的写出来。

  • 应该确保数组足够大, 能够存储字符串中的所有字符,包括空字符。

例子:
char tryee[2] = {'1',';','s'};
错误提示:Excess elements in array initializer

  • 字符常量(如’S’)是字符串编码的简写表示,字符串常量(如”bonjour”)与其不能互换。’S’在ASCII系统上,是’83’的另外一种写法;但”S”就不是字符常量,他表示的是字符S+\0的组合。

1.2. 拼接字符串常量

🍑 例子:

1
cout << "I'd give my right arm to be" "a great violinist.\n";

和下面表达的是等效的。

1
2
cout << "I'd give my right ar"
"m to be a great vionlinist.\n"

1.3. 在数组中使用字符串

下面的code里重点函数为

  1. strlen()

    1
    2
    3
    #include <cstring>

    strlen(一个string) 可以返回string的长度
  2. 截断一个string的操作

在需要阶段的位置替换成’\0’

  1. sizeof()和strlen()的对比

sizeof()运算符是指出整个数组的长度,空字符计算在内
strlen()运算符是指出存储在数组中的字符串的长度,即可见的字符,不计算空字符

完整代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include <iostream>
#include <cstring> //为了使用strlen()工具,来确定字符串的长度


int main()
{
using namespace std;

const int Size = 15;
char name1[Size]; //创建一个空数组
char name2[Size] = "C++owboy"; //初始化数组name2

cout << "Howdy! I am " << name2;
cout << "! What's your name?\n";

cin >> name1;

cout << "Well, " << name1 << ", your name has ";
cout << strlen(name1) << " letters and is stored\n";
cout << "in an array of " << sizeof(name1) << " bytes.\n";

cout << "Your initial is " << name1[0] << ".\n";


//这个操作就截断name2了

name2[3] = '\0'; // set name2 to null character, name2[0],name2[1],name2[2] ...
cout << "Here are the first 3 characters of my name: ";
cout << name2 << endl;



return 0;
}

1.4. 字符串输入

🍑 例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>

int main() {
using namespace std;
const int ArSize = 20;
char name[ArSize];
char dessert[ArSize];

cout << "Enter your name: \n";
cin >> name;
cout << "Enter your favorite dessert: \n";
cin >> dessert;
cout << "I have some delicious " << dessert;
cout << " for you," << name << ".\n";


return 0;
}

要注意的是cin输入的时候,cin使用空白(空格,制表符和换行符)来确定字符串结束的位置,这意味着cin在获取字符串输入时指读取一个单词。

⚠️ 假如输入一个名字Alicia Keys,在这个例子里名字就是Alicia,dessert就是keys,cin一次性得到了两个输入,之后就直接跳到最后一个cout了。

⚠️另外,ArSize的大小为20,如果输入的字符串大于20的长度,也不行哦

1.5. 每次读取一行字符串输入 —— 面对行的输入

1.5.1. getline()将丢弃换行符

getline()将丢弃换行符,通过回车键确认输入结尾,可以使用方法cin.getline()

该函数有两个参数:

  • 第一个参数存储输入行的数组的名称
  • 第二个参数是要读取的字符数(如果这个参数是20,函数最多读取19个字符,最后一个存储空字符)

1.5.2. get()不丢弃换行符

get()的工作原理,参数和getline()类似,但get()不丢弃换行符,而是将其留在输入队列中。

但是不能用连续调用两次get()的方法如下:

🈲️

1
2
cin.get(name,ArSize);
cin.get(dessert,ArSize);

🉑️采用下列做法:

1
2
3
cin.get(name,ArSize);
cin.get();
cin.get(dessert,ArSize);

🉑️也可以这样:

1
2
cin.get(name,ArSize).get(); // concatenate member functions, read newline
cin.get(dessert,ArSize);

1.6. 混合输入字符和数字

混合输入数字和面向行的字符串会导致问题。

修改方法:

  1. 第一种方法

(cin >> year).get()

  1. 第二种方法

cin >> year;
cin.get();

-------------本文结束感谢您的阅读-------------