本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,文章的主题内容均来自该课程,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙
1. 字符数组
回顾 《4. C语言 – 数据类型和取值范围》 可以知道,在 C 语言的数据类型中并没有字符串类型的。那它是如何存放和表示字符串的呢?两种方式——字符串常量以及字符类型的数组。
比如说 “C语言”,"CSDN博客"都是字符串常量,因为是常量,所以也没有办法进行修改,很不方便;另一种就是字符数组,在字符数组中可以先定义指定长度的字符数组,然后再给每个元素单独赋值。
如果给数组中的元素一个一个的赋值的话会导致代码变得冗长,因此可以采用如下四种方法直接在定义的时候对字符数组进行初始化,会方便很多
int main
{
// 初始化字符数组的每个元素
char str1[10] = {'F', 'i', 's', 'h', 'C', '\0'};
// 可以不写元素的个数,因为编译器会自动计算
char str3[] = {'F', 'i', 's', 'h', 'C', '\0'};
// 使用字符串常量初始化字符数组
char str4[] = {"FishC"};
// 使用字符串常量初始化,可以省略大括号
char str5[] = "FishC";
}
在上面的这四种中,推荐使用最后一种,简单方便。
2. 字符串处理函数
在实际开发中,你经常会听到大牛说“避免重新造轮子”。如果能用得上官方提供的现成的函数,尽量不要自己去写,这样除了能够大幅度提供工作效率外,也会使你的程序更加稳定和快速。在这里将介绍几个与字符串有关的函数。
2.1 获取字符串的长度
strlen
的函数原型为
#include <string.h>
...
size_t strlen ( const char * str );
strlen
函数用于返回指定字符串的长度。C 语言字符串的长度取决于结束符(’\0’)的位置,一个字符串的长度指的是从起始位置到结束符的字符个数(不包含结束符本身)。初学者很容易混淆字符串的长度和字符串数组的大小,例如:
char mystr[100] = "I love FishC.com!";
上边代码定义一个可以存放 100 个字符的数组,但 mystr 字符串只被初始化为包含 17 个字符的长度。因此,sizeof(mystr) 的结果是 100,而 strlen(mystr) 的结果则是 17。
一个具体的例子如下所示
#include <stdio.h>
#include <string.h>
int main()
{
char str[100] = "I love FishC.com!";
printf("length = %u\n", strlen(str));
return 0;
}
得到如下的结果
其中需要注意的是 size_t
被定义于 stddef.h
头文件中,它事实上就是无符号整形(unsigned int
),所以在打印输出中使用 %u
进行占位。
2.2 字符串处理函数
在字符串中需要注意的是,字符串不可以像常量一样通过赋值符号进行拷贝,常用 strcpy
函数和 strncpy
函数拷贝字符串。
2.2.1 strcpy
函数
strcpy
函数用于拷贝字符串,包含最后的结束符 ‘\0’。为了避免溢出,必须确保用于存放的数组长度足以容纳待拷贝的字符串(注意:长度需要包含结束符 ‘\0’)。
strcpy
的函数原型为
#include <string.h>
...
char *strcpy(char *dest, const char *src);
其中 dest 指向用于存放字符串的目标数组,src 指向待拷贝的源字符串,简单理解就是就是将位与后面字符串中的内容拷贝到前面的字符串中。返回值为指向目标字符串的指针。
下面是举例说明这个函数的功能
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "Original String";
char str2[] = "New String";
char str3[100];
strcpy(str1, str2);
strcpy(str3, "Copy Successful");
printf("str1: %s\n", str1);
printf("str2: %s\n", str2);
printf("str3: %s\n", str3);
return 0;
}
执行上面代码得到如下
2.2.2 拷贝字符串(受限)
和 strcpy
函数一样,strncpy(dest, src, n)
函数将拷贝源字符串的 n 个字符到目标数组中。如果源字符串的长度小于 n,那么就用 ‘\0’ 填充额外的空间。如果源字符串的长度大于或等于 n,那么只有 n 个字符被拷贝到目标数组中(注意:这样的话将不会以结束符 ‘\0’ 结尾)。为了使该函数更“安全”,建议使用 dest[sizeof(dest) - 1] = '\0'
; 语句确保目标字符串是以 ‘\0’ 结尾。
它的函数原型如下
#include <string.h>
...
char *strncpy(char *dest, const char *src, size_t n);
其中 dest 指向存放字符串的目标数组,src 指向待拷贝的源字符串,n 指定拷贝的最大长度,返回值是指向目标字符串的指针。
比如说执行如下的代码,将 str1 拷贝到 str2,将 str2 拷贝到 str3。
#include <stdio.h>
#include <string.h>
int main()
{
char str1[] = "To be or not to be";
char str2[40];
char str3[40];
strncpy(str2, str1, sizeof(str2));
strncpy(str3, str2, 5);
str3[5] = '\0';
printf("%s\n", str1);
printf("%s\n", str2);
printf("%s\n", str3);
return 0;
}
其中需要注意的是,我们特意加上 str3[5] = '\0';
,确保目标字符串是以 ‘\0’ 结尾。执行可以得到如下的结果
To be or not to be
To be or not to be
To be
2.3 连接字符串
同样连接字符串也有 strcat
函数和 strncat
函数两种。
2.3.1 strcat
函数
strcat 函数用于连接两个字符串。将源字符串拷贝并连接到目标数组存放的字符串后边,此过程将覆盖第一个参数的结束符 ‘\0’。
具体的函数原型为
#include <string.h>
...
char *strcat(char *dest, const char *src);
其中 dest 指向用于存放字符串的目标数组,它应该包含一个字符串,并且提供足够容纳连接后的总字符串长度的空间(包含结束符 ‘\0’);src 指向待连接的源字符串,该参数不应该与 dest 参数指向的位置发生重叠;返回值是指向目标字符串的指针。
比如执行如下的程序
#include <stdio.h>
#include <string.h>
int main()
{
char str1[100] = "Original String";
char str2[] = "New String";
strcat(str1, " ");
strcat(str1, str2);
printf("str1: %s\n", str1);
return 0;
}
执行上面的代码可以得到如下的结果
str1: Original String New String
其中需要注意的是,我们首先在 str1 的后面连接了一个空格,之后在连接的 str2 ,否则显示的时候两个字符串会连在一起。
2.3.2 strncat 函数
strncat
函数用于拷贝源字符串中的 n 个字符到目标数组的字符串后边,并在末尾添加结束符 ‘\0’。如果源字符串的长度小于 n,那么不会像 strncpy 函数那样使用 ‘\0’ 进行填充(但结束符 ‘\0’ 还是有的)。另外,目标数组中的原有的字符串并不算在 n 中。
函数原型如下
#include <string.h>
...
char *strncat(char *dest, const char *src, size_t n);
其中 dest
指向用于存放字符串的目标数组,它应该包含一个字符串,并且提供足够容纳连接后的总字符串长度的空间(包含结束符 ‘\0’);src 指向待连接的源字符串,该参数不应该与 dest 参数指向的位置发生重叠;n 指定待连接的源字符串的最大长度。返回值是指向目标字符串的指针。
下面是strncat
函数的举例说明
#include <stdio.h>
#include <string.h>
int main()
{
char str1[20] = "I ";
char str2[20] = "love ";
char str3[20] = "FishC.com!";
strncat(str1, str2, 5);
strncat(str1, str3, 10);
printf("str1: %s\n", str1);
return 0;
}
执行得到如下的结果
str1: I love FishC.com!
2.4 比较字符串
2.4.1 strcmp 函数
strcmp 函数用于比较两个字符串。该函数从第一个字符开始,依次比较每个字符的 ASCII 码大小,直到发现两个字符不相等或抵达结束符(’\0’)为止。
函数原型如下
#include <string.h>
...
int strcmp(const char *s1, const char *s2);
其中s1 指向待比较的字符串 1,s2 指向待比较的字符串 2。当字符串 1 的字符小于字符串 2 对应位置的字符,返回值 < 0;当两个字符串的内容完全一致,返回值 = 0;字符串 1 的字符大于字符串 2 对应位置的字符,返回值 > 0。
如下所示
#include <stdio.h>
#include <string.h>
int main()
{
char str1[10] = "FishC.com";
char str2[20] = "FishC.com";
if (!strcmp(str1, str2)){
printf("两个字符串完全一致!\n");
}
else{
printf("两个字符串不同!\n");
}
return 0;
}
执行代码可得
两个字符串完全一致!
2.4.2 strncmp 函数
strncmp
函数用于比较两个字符串的前 n 个字符。该函数从第一个字符开始,依次比较每个字符的 ASCII 码大小,发现两个字符不相等或抵达结束符(’\0’)为止,或者前 n 个字符完全一样,也会停止比较。
函数原型如下
#include <string.h>
...
int strncmp(const char *s1, const char *s2, size_t n);
s1 指向待比较的字符串 1,s2 指向待比较的字符串 2,n 指定待比较的字符数,返回值与上面 strcmp 的返回值相同。
比如执行如下的代码
#include <stdio.h>
#include <string.h>
int main()
{
char str1[40] = "FishC";
char str2[40] = "FishC.com";
if (!strncmp(str1, str2, 5))
{
printf("str1和str2前5个字符相同!\n");
}
else
{
printf("str1和str2前5个字符不同!\n");
}
return 0;
}
可以得到如下的结果
str1和str2前5个字符相同!
参考
[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P19
欢迎大家关注我的知乎号(左侧)和经常投稿的微信公众号(右侧)