Skip to content
Word Count: 970 | Expected Read Time: 3 min

APS105预习 - 07

Chapter 10 Strings 字符串

在之前的章节中,我们讨论了char类型,类似的,我们将存储单词或者句子的容器叫做字符串

10.1什么是字符串

要将字符串存储在变量中,需要使用字符数组。需要注意的是,该字符数组有一个ASCII码为0的空字符做结尾,也就是\0。我们可以用三种不同的方式在空字符终止的字符数组中设置字符串。

方法1:声明并且初始化

1
char myString[] = "Hello";

注意⚠️:该字符数组有6个元素(不是5个),最后末尾的\0不可见

当然,也可以为字符数组设置一个大于字符串长度+1的长度,多余的位置将由\0填充

方法2: 先声明,稍后初始化

1
2
3
char myString[4];
myString[0] = "A";
......

方法3: 声明一个指向常量字符串的指针

1
char* pStr = "Wow";

这个操作会创建一个存储有指向字符串第一位的内存地址的指针,实际的字符数组会被存储在常量和全局变量内存段

注意⚠️:由于常量字符串指针是常量,尝试更改其指向的值的操作会导致程序静默失败。但是,更改其指向的内存是被允许的

内存示意图

由于此处的pStr是一个指针,所以我们可以更改他所指向的位置。例如,可以将该常量字符串指针指向栈内存。当指针指向堆栈内存的时候,该数组的元素可以像其他数组一样被修改,例如:

1
2
3
4
5
char* pStr = "Wow";
char str[] = "It";

pStr = str;
pStr[1] = "A"; // This is valid.

\0的用处

什么,0的用处?

空字符可以让程序编写者在不知道字符数组大小的情况下用来指导字符串在何处结束。例如以下代码可以用来统计任意长度的字符串内所含空格数量:

1
2
3
4
5
6
7
8
9
int spacesCount(char str[]) {
int count = 0;
for (int ind = 0; str[ind] != '\0'; ind++) {
if (str[ind] == ' ') {
count++;
}
}
return count;
}

10.2 字符串IO

字符串的输出

就想C语言中的其他数据类型一样,字符串的输出依然得仰仗亲爱的printf()兄弟。

字符串的格式标识符是%s,当打印的时候,printf会答应\0前的所有字符

1
2
3
4
5
6
7
8
#include <stdio.h>

int main(void) {
char s[] = "Hello";
printf("%s\n", s);
printf("%s\n", s+2); //Start printing from the index 2.
return 0;
}

如果我们希望答应特定数量的字符,可以使用%.*s的格式说明符,将*替换为要打印的字符数量。

我想偷懒!!!!

C语言提供了一种给懒人的字符串输出方法,他叫……puts()

1
2
3
4
5
6
7
#include <stdio.h>

int main(void) {
char s[] = "Hello";
puts(s);
return 0;
}

字符串输入

在读入字符串,我们也要使用%s格式说明符,例如:

1
2
char str[10];
scanf("%s", str); // NOT &str

为啥不是&str呢?

当输入的字符串长度大于字符数组的大小的时候,scanf会发生缓冲区溢出,这意味着程序将会在数组大小之外的内存位置进行未定义的写入

使用fgets()以避免scanf()中的缓冲区溢出

1
2
3
4
5
6
7
8
#include<stdio.h>
int main(void){
char st[7+1];
print("Enter a String: \n");

fgets(st, 3, stdin);
......
}

fgets 接受三个输入参数。在上面的例子中,我们为这些参数使用了以下值。

  1. st :指向字符数组第一个元素的指针。
  2. 3 :要读取的最大字符数加 1。额外的字符用于在从用户读取的字符后存储一个空字符。
  3. stdin :输入流。在这种情况下,我们是从用户那里获取输入,该输入存储在 stdin —— 一个在 stdio.h 库中定义的文件中。

getchar()

C语言中,也可以使用getchar()来获取单个字符

About this Post

This post is written by Jinyuan Zhou, licensed under CC BY-NC 4.0.

#APS105 #C/C++ #预习 #笔记