目录
一. strlen函数
1.1 strlen函数实现的功能及函数原型
1.1.1 strlen函数实现的功能
strlen函数统计某个字符串的有效字符数(不包含末尾的'\0')。
1.1.2 strlen的函数原型
查阅MSDN,strlen的函数原型为:size_t strlen( const char *string );
- 该函数有一个输入参数,为字符串的名称(字符串首个字符元素的地址)
- 该函数的返回值类型为size_t,即无符号整型,表示字符串中的有效字符数
- 使用该函数需要引用头文件<string.h>
1.1.3 strlen实现功能的更进一步解读
许多初学者看到strlen函数,可能会认为strlen函数接受的参数只能是表示首元素地址的字符串名称,其实不是。传入的参数可以是任何一个地址(指针变量),strlen函数在求解字符串有效字符数时,以传入的地址为起始点向后查询字符串终止标识符'\0',在查找到'\0'之前共有几个内存空间的内容不是'\0'字符串的有效字符数就是几。strlen的功能图解如图1.1所示。
![](https://img-blog.csdnimg.cn/1ccd6f069f1743d8b22d85a61e2aecef.png)
1.2 strlen函数的使用方法演示
下段代码中定义了字符串arr[]="abcdef",分别将arr和arr+1作为参数传入strlen函数进行计算,得到的结果分别为6和5。
#include<stdio.h>
int main()
{
char arr[] = "abcdef";
size_t len1 = strlen(arr);
size_t len2 = strlen(arr + 1);
printf("len1=%u len2=%u\n", len1, len2); //打印len1=6 len2=5
return 0;
}
1.3 strlen函数的三种模拟实现方法
1.3.1 通过计数的方法模拟实现strlen函数
每在内存中查找到一个不是'\0'的字符,就进行count++操作,遇到'\0'就终止计数。
代码演示:
size_t my_strlen(const char* str)
{
assert(str); //传入指针的有效性检验
size_t count = 0;
while (*str++ != '\0')
{
count++;
}
return count;
}
1.3.2 通过递归的方法模拟实现strlen函数
代码演示:
size_t my_strlen(const char* str)
{
assert(str);
if (*str != '\0')
{
//*str != '\0'时就将下一个地址传入my_strlen递归调用
return 1 + my_strlen(str + 1);
}
else
{
return 0;
}
}
1.3.3 使用指针相减的方法来模拟实现strlen函数
两指针相减的结果是两个指针指向的内存位置之间存储的元素的个数。因此,只需确定存储'\0'的内存的地址,与首元素地址相减,就得到了字符串的有效字符数。
size_t my_strlen(const char* str)
{
assert(str);
char* start = str;
while (*str != '\0') //获取存储'\0'的内存地址
{
str++;
}
return str - start;
}
二. strcpy函数
2.1 strcpy函数实现的功能及函数原型
2.1.1 strcpy函数实现的功能
将源字符串的内容复制到目标字符串,包括源字符串末尾的'\0'也会被复制到目标字符串。
注意:目标字符串一定要有足够的空间来容纳源字符串,否则将出现不可预料的结果。
2.1.2 strcpy函数的函数原型
查阅MSDN,strcpy的函数原型为:
char *strcpy( char *strDestination, const char *strSource );
函数有两个输入参数:
- strDestination,目标字符串空间,用于容纳复制后的源字符串。
- strSource,源字符串。
函数的返回值类型为char*,返回目标字符串首元素的地址。
2.2 strcpy函数的使用方法演示
代码段1定义了两个字符串:arr1[10]="xxxxxxxxx",arr2[10]="abcd",以arr2为源字符串,arr1为目标字符串,将arr2的内容复制到arr1中去,打印arr1,结果为abcd。
代码段1:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[10] = "xxxxxxxxx";
char arr2[10] = "abcd";
strcpy(arr1, arr2);
printf("arr1 = %s\n", arr1); //arr1 = abcd
return 0;
}
由代码段2,若arr1的空间不足以容纳arr2,程序发生崩溃。运行结果如图2.1所示
代码段2:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[10] = "xxxxxxxx";
char arr2[15] = "abcdefghiklmn";
strcpy(arr1, arr2);
printf("arr1 = %s\n", arr1);
return 0;
}
![](https://img-blog.csdnimg.cn/ebe2c6bbc77a40159324bc1438b1ec45.png)
2.3 strcpy的模拟实现
代码演示:
#include<stdio.h>
#include<assert.h>
char* my_strcpy(char* str1, const char* str2)
{
assert(str1 && str2);
char* ret = str1;
while (*str1++ = *str2++)
{
;
}
return ret;
}
三. strcat函数
3.1 strcat函数实现的功能及函数原型
3.1.1 strcat函数实现的功能
将源字符串追加到目标字符串的尾部,包括'\0'。图3.1为strcat函数的功能图解。
![](https://img-blog.csdnimg.cn/ce8fa954565541eb86333998b843cee6.png)
注意:必须确保源字符串留有足够的空间容纳目标字符串,否则会出现不可预料的结果
3.1.2 strcat函数的函数原型
查阅MSDN,strcat的函数原型为:
char *strcat( char *strDestination, const char *strSource );
strcat函数有两个输入参数:
- strDestination,目标字符串首元素地址
- strSourc,源字符串首元素地址
函数的返回值类型为字符指针(char*),返回值为目标字符串首元素地址。
3.2 strcat函数的使用方法演示
下段代码定义了两个字符串:arr1[20] = "xxxxxx",arr2[10] = "abc"。将arr1作为目标字符串、arr2作为源字符串传入函数strcat,并打印arr1字符串,结果为:xxxxxxabc
代码演示:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[20] = "xxxxxx";
char arr2[15] = "abc";
strcat(arr1, arr2);
printf("arr1 = %s\n", arr1); //arr1 = xxxxxxabc
return 0;
}
3.3 strcat函数的模拟实现
首先获取目标空间字符串中第一次出现'\0'的地址,然后将源字符串的数组依次复制到目标字符串最后一个有效字符后面,当发现源字符串中有'\0'时,停止复制。
模拟实现strcat函数的代码:
char* my_strcat(char* dest, const char* src)
{
char* ret = dest; //返回值
while (*dest != '\0')
{
dest++; //查找目标字符串第一次出现'\0'的位置
}
while (*dest++ = *src++) //复制到'\0'终止
{
;
}
return ret;
}
四. strcmp函数
4.1 strcmp函数的功能及函数原型
4.1.1 strcmp函数实现的功能
strcmp函数是字符串大小比较函数,通过返回值的大小可以获取两个字符串的大小
两个字符串的大小关系是如何定义的?
假设arr1[ ] = "12abf",arr2[ ] = "12dbf"
先比较两个字符串的首字符,一样,再比较第二个字符,一样,将两个字符串的每个字符依次进行比较,直到遇到不一样的字符,比较两字符串首个不一样的字符的ASCII码值,来确定两个字符串的大小关系。若arr1和arr2有效字符数相同,且所有字符均相同,则arr1与arr2相等。
注意:两个字符串之间比较大小不能使用==,如果使用==对两个字符串进行比较,那么实际上是比较两个字符串首元素的地址,而地址的比较没有任何意义。
4.1.2 strcmp函数的函数原型
查阅MSDN,strcmp的函数原型为:
int strcmp( const char *string1, const char *string2 );
函数有两个输入参数,即两个用于比较的字符串。
函数返回值为int类型,返回值的正负表示两个字符串的大小:
- 若返回值 <0 :则string1 < string2
- 若返回值 >0:则string1 > string2
- 若返回值<0:则string1 = string2
4.2 strcmp函数的使用方法演示
下面程序中定义了两个字符串:arr1[]="abcd"、arr2[]="abdd"。arr1和arr2的前两个字符相同,arr1的第三个字符的ASCII码值小于arr2的第三个字符,因此arr1<arr2。调用函数strcmp(arr1,arr2)的返回值<0,程序打印<。
代码演示:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcd";
char arr2[] = "abdd";
int ret = strcmp(arr1, arr2); //arr1 < arr2
if (ret < 0)
{
printf("<\n");
}
else if (ret > 0)
{
printf(">\n");
}
else
{
printf("=\n");
}
return 0;
}
4.3 strcmp函数的模拟实现
模拟实现strcmp函数的代码:
int my_strcmp(const char* str1, const char* str2)
{
while (*str1 == *str2)
{
if (*str1 == '\0') //检查到末尾依旧相同,两字符串相等
{
return 0; //两字符串相等返回0
}
str1++; //下一个字符地址
str2++;
}
return *str1 - *str2; //返回值为首次不相同的字符串相减
}
五. strncpy函数
5.1 strncpy函数的功能及函数原型
5.1.1 strncpy函数的功能
将源字符串的前n个字符复制到目标字符串前n个字符的位置。通俗的说,就是把目标字符串的前n个字符元素替换为目标字符串的前n个元素。
对于strncpy函数的具体实现,分为两种情况来讨论:
- 当源字符串的有效字符数目大于或等于要求复制的字符数目n时,将源字符串的前n个字符复制到目标字符串前n个字符的位置,目标字符串第n个字符往后的内容不发生改变。图5.1为这种情况下strncpy函数实现的图解。
- 当源字符串的有效字符数目小于要求复制的字符数目n时,先将源字符串的有效字符复制到目标字符串,然后看源字符串有效字符数比要求复制的字符数少了几个,少几个就在相应目标字符串的位置补几个'\0'字符。图5.2为这种情况下strncpy函数实现的图解。
![](https://img-blog.csdnimg.cn/e159cce6524c4b12a8367062e870ac7c.png)
![](https://img-blog.csdnimg.cn/bcde63f8dc884b5f88af7f4201448e79.png)
5.1.2 strncpy的函数原型
查阅MSDN,strncpy的函数原型为:
char *strncpy( char *strDest, const char *strSource, size_t count );
函数有三个输入参数:
- strDest,目标字符串
- strSource,源字符串
- count,要复制的字符数目
函数的返回值类型为字符型指针(char*),返回目标字符串首元素的地址。
5.2 strncpy函数的使用方法演示
- 源字符串的有效字符数目大于或等于要求复制的字符数目的情况
在代码段5.2.1中,定义两个字符串:arr1[15]="##########"和arr2[ ]="abcedf",执行指令strncpy(arr1,arr2,3),将arr2中的前三个字符复制到arr1中去,并打印arr1。
程序运行的结果为:arr1 = abc#######
代码段5.2.1:
int main()
{
char arr1[15] = "##########";
char arr2[] = "abcdef";
char* ret = strncpy(arr1, arr2, 3);
printf("arr1 = %s\n", arr1); //arr1 = abc#######
return 0;
}
- 源字符串的有效字符数目小于要求复制的字符数目的情况
在代码段5.2.2中,定义两个字符串:arr1[15]="##########"和arr2[ ]="abc",执行指令strncpy(arr1,arr2,5),将arr2中的前5个字符复制到arr1中去,并打印arr1。
程序运行结果为:arr1 = abc
代码段5.2.2:
int main()
{
char arr1[15] = "##########";
char arr2[] = "abc";
char* ret = strncpy(arr1, arr2, 5);
printf("arr1 = %s\n", arr1); //arr1 = abc
return 0;
}
进入调试,打开监视窗口,观察执行完strncpy(arr1,arr2,5)指令后arr1的变化情况,可以看到,arr1的前三个元素变为了'a'、'b'、'c',第四和第五个元素均变为了'\0'、'\0'。执行完strncpy(arr1,arr2,5)后的监视窗口如图5.3所示。
![](https://img-blog.csdnimg.cn/6505cec9cab14e1092172542a10dd1e1.png)
5.3 strncpy函数的模拟实现
strncpy模拟实现的代码:
#include<stdio.h>
#include<string.h>
char* my_strncpy(char* str1, const char* str2, size_t n)
{
char* ret = str1;
while ((*str2 != '\0') && n) //复制n个字符串到str1,遇*str2='\0'终止复制
{
*str1 = *str2;
str1++;
str2++;
n--;
}
if (n > 0)
{
//str2中有效字符数小于n时arr1后方补'\0'
while (n--)
{
*str1++ = '\0';
}
}
return ret;
}
六. strncat函数
6.1 strncat函数的功能和函数原型
6.1.1 strncat函数实现的功能
strnact函数为限制长度的字符串追加函数,将源字符串的前n个字符追加到目标字符串的后方。注意:要确保目标字符串留有足够的空间容纳源字符串,否则程序将产生不可预料的结果。
分两种情况来讨论:
- 当源字符串有效字符数目小于或等于要求追加的字符数n时,直接将源字符串的前n个字符追加到目标字符串的后面。图解可参考图6.1。
- 当源字符串有效字符数目小于要求复制的字符数时,则在源字符串中遇到了一个'\0'后就终止追加。图解可参考图6.2。
![](https://img-blog.csdnimg.cn/bff8d38e1fe046f1a55debae6c864651.png)
![](https://img-blog.csdnimg.cn/f670bace669d452eb75dca51cc9f40b1.png)
6.1.2 strncat的函数原型
查阅MSDN,strncat的函数原型为:
char *strncat( char *strDest, const char *strSource, size_t count );
该函数有三个输入参数:
- strDest,目标字符串(被追加的字符串)
- strSource,源字符串
- count,要追加的字符串数目
该函数的返回值为目标字符串(strDest)首元素的地址
6.2 strncat函数的使用方法演示
- 源字符串有效字符数目小于或等于要求追加的字符数时
代码段6.2.1实现的功能为在arr1后方追加arr2的前三个字符,然后打印arr1。
程序运行的结果为:arr1 = ####abc
代码段6.2.1:
int main()
{
char arr1[15] = "####";
char arr2[] = "abcdef";
char* ret = strncat(arr1, arr2, 3);
printf("arr1 = %s\n", ret); //arr1 = ####abc
return 0;
}
- 源字符串有效字符数目大于要求追加的字符数时
代码段6.2.2定义了两个字符串:arr1[15] = "####\0######"和arr2[] = "abc",strncat(arr1, arr2, 5)语句希望将arr2的前5个字符追加到arr1后面(从arr1中第一个\0的位置开始追加),但是arr2仅有三个有效字符,因此,先追加arr2全部的三个有效字符,使得arr1中从原来第一个\0位置处开始的三个字符,依次变为'a'、'b'、'c',然后再'c'后面追加'\0'。
程序运行的结果为:arr1 = ####abc
代码段6.2.2:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[15] = "####\0######";
char arr2[] = "abc";
char* ret = strncat(arr1, arr2, 5);
printf("arr1 = %s\n", ret); //arr1 = ####abc
return 0;
}
进入调试界面,打开监视窗口,监视arr1在执行完strncat(arr1, arr2, 5)语句后的变化情况。执行完strncat(arr1, arr2, 5)语句后的监视窗口如图6.3所示。
![](https://img-blog.csdnimg.cn/3c7d00f163b54770ba68a478de40d346.png)
6.3 strncat函数的模拟实现
strncat函数模拟实现的代码:
char* my_strncat(char* dest, const char* src, size_t n)
{
assert(dest && src); //指针的有效性检查
char* ret = dest;
while (*dest != '\0') //查找源字符串第一次出现\0的位置
{
dest++;
}
while ((*src != '\0') && n)
{
//将src的前n个字符(所有有效字符)追加到目标字符串后面
*dest++ = *src++;
n--;
}
*dest = '\0'; //追加完成后补'\0'
return ret;
}
七. strncmp函数
7.1 strncmp函数的功能和函数原型
7.1.1 strncmp函数的功能
strncmp是限制长度的字符串比较函数,将arr1和arr2的前n个字符视为具有n个有效字符的字符串,比较arr1和arr2前n个字符组成的字符串的大小。如果在比较过程中遇到了'\0'字符,则停止比较。
当还没有比较完前n个字符就遇到'\0'时,分两种情况讨论:
- 两个字符在比较过程中同时遇到'\0',如定义arr1[]="abc",arr2[]="abc",执行语句strncmp(arr1, arr2, 5),但由于arr1和arr2前三个字符相同,到了第四个字符就遇到了'\0',因此,比较到第四个字符就停止比较,不再比较第五个字符,arr1与arr2相等。
- 两个字符在比较过程中其中一个遇到'\0',如定义arr1[]="ab",arr2[]="abcdef",执行语句strncmp(arr1, arr2, 4),比较到第三个字符时arr1就遇到了'\0',arr2的第三个字符为c,'\0'的ASCII码值小于'c'。因此arr1<arr2。
7.1.2 strncmp函数的原型
查阅MSDN,得strncmp的函数原型为:
int strncmp( const char *string1, const char *string2, size_t count );
有三个输入参数:
- string1和string2:两个用于比较的字符串
- count:比较的字符数目
函数的返回值为int类型,通过返回值的正负比较大小
- 若 返回值>0:arr1 > arr2
- 若 返回值<0:arr1 < arr2
- 若 返回值=0:arr1 = arr2
7.2 strncmp的使用方法演示
代码段7.2.1定义了字符串arr1[]="abcde"和arr2[]="abce",执行语句strncmp(arr1,arr2,3)和strncmp(arr1,arr2,4),分别比较arr1和arr2前3和前四个字符组成的字符串的大小,arr1和arr2的前三个字符进行比较结果相等,前四个字符进行比较arr1<arr2。
代码运行的结果为:= <
代码段7.2.1:
#include<stdio.h>
#include<string.h>
int main()
{
char arr1[] = "abcde";
char arr2[] = "abce";
int ret = strncmp(arr1, arr2, 3); //比较arr1和arr2的前三个字符,结果为=
if (ret > 0)
{
printf("> ");
}
else if (ret < 0)
{
printf("< ");
}
else
{
printf("= ");
}
ret = strncmp(arr1, arr2, 4); //比较arr1和arr2的前四个字符,结果为<
if (ret > 0)
{
printf(">\n");
}
else if (ret < 0)
{
printf("<\n");
}
else
{
printf("=\n");
}
return 0;
}
7.3 strncmp函数的模拟实现
strncmp函数的模拟实现代码:
#include<stdio.h>
#include<string.h>
#include<assert.h>
int my_strncmp(const char* str1, const char* str2, size_t count)
{
assert(str1 && str2);
while ((*str1 == *str2) && count)
{
if (*str1 == '\0') //同时遇到'\0',arr1=arr2
{
return 0;
}
str1++;
str2++;
count--;
}
if (0 == count)
{
return 0;
}
else
{
return *str1 - *str2;
}
}
全文结束,感谢大家的阅读,敬请批评指正。