【C语言速成】12. 字符串和string.h
字符串是一段连续的文字,它的本质是char数组。
创建字符串
创建一个叫s1的能装9个字符的字符串:
char s1[10];
为什么s1的容量是10却只能装9个字符?因为C语言程序中的字符串需要一个额外的空字符(ASCII为0)来标记字符串的结束。也就是说如果有一个字符串的内容是"Hello",那么它实际上包含{'H', 'e', 'l', 'l', 'o', 空字符}
这个六个字符。操作字符串时一定要确保空字符有位置放,否则程序会出bug。
在创建字符串时提供初始值:
修改字符串的内容
有这样一段代码:
这段代码很容易理解,它使用char数组存储“Steve”,之后将它的内容改为“Alex”,然而到了编译的时候你就会发现编译器在第七行(也就是修改内容的那行)报错了。这是因为C语言不允许把字符串字面值(像"Alex"这样在代码里写死了的值)直接赋值给char数组。
要想把字符串字面值赋值给char数组,需要使用string.h头文件中的strcpy
函数:
/**
* 将一个字符串的内容复制到另一个字符串。
* 注意:
* @param dest 目标字符串。
* @param src 提供内容的字符串。
* @return 指向目标字符串首元素的指针。
*/
char* strcpy(char* dest, const char* src)
修正后的代码如下:
基于char指针的字符串
上面讲到的字符串是基于char数组的,C语言还有一种字符串实现是基于char指针的,这样的字符串一经初始化就不能通过下标来修改内容,只能使用string.h中提供的函数来进行拼接、裁剪、赋值等操作。但是这样的字符串可以直接用字面值赋值,也就是说如果存在char* s = "Steve";
,那么s = "Alex";
不会出现问题。
读取输入到字符串
示例
代码:
用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)