【C语言速成】12. 字符串和string.h

字符串是一段连续的文字,它的本质是char数组。

创建字符串

创建一个叫s1的能装9个字符的字符串:

char s1[10];

为什么s1的容量是10却只能装9个字符?因为C语言程序中的字符串需要一个额外的空字符(ASCII为0)来标记字符串的结束。也就是说如果有一个字符串的内容是"Hello",那么它实际上包含{'H', 'e', 'l', 'l', 'o', 空字符}这个六个字符。操作字符串时一定要确保空字符有位置放,否则程序会出bug。

在创建字符串时提供初始值:

enter image description here

修改字符串的内容

有这样一段代码:

enter image description here

这段代码很容易理解,它使用char数组存储“Steve”,之后将它的内容改为“Alex”,然而到了编译的时候你就会发现编译器在第七行(也就是修改内容的那行)报错了。这是因为C语言不允许把字符串字面值(像"Alex"这样在代码里写死了的值)直接赋值给char数组。

要想把字符串字面值赋值给char数组,需要使用string.h头文件中的strcpy函数:

/**
 * 将一个字符串的内容复制到另一个字符串。
 * 注意:
 * @param dest 目标字符串。
 * @param src 提供内容的字符串。
 * @return 指向目标字符串首元素的指针。
 */
char* strcpy(char* dest, const char* src)

修正后的代码如下:

enter image description here

基于char指针的字符串

上面讲到的字符串是基于char数组的,C语言还有一种字符串实现是基于char指针的,这样的字符串一经初始化就不能通过下标来修改内容,只能使用string.h中提供的函数来进行拼接、裁剪、赋值等操作。但是这样的字符串可以直接用字面值赋值,也就是说如果存在char* s = "Steve";,那么s = "Alex";不会出现问题。

enter image description here

读取输入到字符串

示例

代码:

enter image description here

用scanf函数读取输入到字符串时,不需要在参数列表里的char数组名字前边加取地址符,因为使用数组名相当于使用指向这个数组首元素的指针(《数组和指针》一节中提到过)。

输入和输出:

【电脑】What's your name?
【你】Rain Silves(回车)
【电脑】Your name is Rain

可以看到s被赋值成了“Rain”而不是输入的“Rain Silves”,这是因为%s描述符表示不间断的字符,所以scanf读到“Rain”后边的空格时就不继续读取输入了,“Silves”将会留在输入中,等到被下一次调用scanf函数时读取。

如果想读取包含空格的整行,可以把scanf读取的格式改成"%19[^n]",这样scanf就会持续读取字符,直到遇到换行符或者读取了19个字符为止。

string.h中的常用函数

/**
 * 获取字符串的长度(不算空字符)。
 * @param str 需要检测的字符串。
 * @return 字符串的长度。
 * 注意:字符串末尾没有空字符时,此函数返回值无效。
 */
size_t strlen(const char* str)
/**
 * 复制一部分字符到另一个字符串。
 * @param dest 目标字符串的。
 * @param src 提供内容的字符串。
 * @param count 复制多少个字符?
 * @return 目标字符串。
 * 注意:务必确保strlen(src)小于dest的容量。
 */
char* strncpy(char* dest, const char* src, size_t count)
/**
 * 在字符串末尾连接内容。
 * @param dest 目标字符串。
 * @param src 提供内容的字符串。
 * @return 目标字符串。
 * 注意:务必确保strlen(dest)+strlen(src)小于dest的容量。
 */
char* strcat(char* dest, const char* src)
/**
 * 在字符串末尾连接另一字符串的部分内容。
 * @param dest 目标字符串。
 * @param src 提供内容的字符串。
 * @param count 拼接多少个字符?
 * @return 目标字符串。
 */
char* strncat(char* dest, const char* src, size_t count)
/**
 * 查找某字符在字符串中首次出现的位置。
 * @param str 待分析的字符串。
 * @param ch 要查找的字符。
 * @return 指向找到的字符的指针。如果没找到,返回NULL。
 */
char* strchr(const char* str, int ch)
/**
 * 按长度和ASCII比较两个字符串。
 * @param l 第一个字符串。
 * @param r 第二个字符串。
 * @return 如果两字符串内容一致,返回0;
 *         如果l比r长,或者l的第一个和r不一样的字符的ASCII比r的大,返回正数;
 *         如果l比r短,或者l的第一个和r不一样的字符的ASCII比r的小,返回负数。
 */
int strcmp(const char* l, const char* r)
/**
 * 按长度和ASCII比较两个字符串的部分内容。
 * @param l 第一个字符串。
 * @param r 第二个字符串。
 * @param count 最多比较多少个字符?
 * @return 和strcmp相同,除了比较范围不一样。
 * 注意:务必确保count小于等于strlen(较短的字符串)。
 */
int strncmp(const char* l, const char* r, size_t count)
/**
 * 查找某字符串在字符串中首次出现的位置。
 * @param str 待分析的字符串。
 * @param substr 需要查找的字符串。
 * @return 指向str中substr首次出现位置的指针。如果没找到或者substr是NULL,返回NULL。
 */
char* strstr(const char* str, const char* substr)
标签