目录
一,函数介绍
1.1函数介绍
求字符串长度的函数
strlen的函数参数和返回类型如下
size_t strlen ( const char * str );
![07ec774be8fa435b9d0288a6ac6fc9e2.png](https://img-blog.csdnimg.cn/direct/07ec774be8fa435b9d0288a6ac6fc9e2.png)
如上图,因为arr1存放的是的是字符串但是在结尾处加了一个 '\0'
而在arr2中我们可以看到,他并没有在他最后面补一个 '\0'
但是为什么arr2用strlen求的是23呢,我们可以看下图
我们可以看到,如果在arr2中没有放'\0' 那么strlen 函数会一直往下找直到找到'\0'才停止
1.2 strcpy
字符拷贝函数
我们先来看strcpy函数的参数和返回类型
char* strcpy(char* destination,const char* source);
如果成功拷贝,他返回地址是 char* destination 的首地址,用const修饰 char* source 是防止对他进行修改
当然在使用这个函数的时候也是有一些要求的
源字符串必须以 '\0' 结束,因为拷贝字符串的长度可能没有destination指向的字符串长会使打印结果出现问题,所以在使用strcpy的时候会将源字符串中的 '\0' 拷贝到目标空间。目标空间必须足够大,以确保能存放源字符串,不然可能会出现越界访问。目标空间必须可变,不能是常量字符串,因为常量字符串是不能被改变的。
![b471dee7ab594c3985b802657bcf6be6.png](https://img-blog.csdnimg.cn/direct/b471dee7ab594c3985b802657bcf6be6.png)
1.3strcat
字符串追加函数
char* strcat(char* destination, const char* source);
该函数返回是的目标字符串首元素的地址,是将源字符串拷贝到目标字符串后面,因为不会改变源字符串所以用const来修饰源字符串
下面我们就说一下在使用strcat需要注意的事项
![48c267cea85f43349d46091a40c4f400.png](https://img-blog.csdnimg.cn/direct/48c267cea85f43349d46091a40c4f400.png)
![fa16ec94f0f94024913a654e7b244d99.png](https://img-blog.csdnimg.cn/direct/fa16ec94f0f94024913a654e7b244d99.png)
![de0d50b18074417b9af0e07f42d42a99.png](https://img-blog.csdnimg.cn/direct/de0d50b18074417b9af0e07f42d42a99.png)
1.4strcmp
字符串比较函数
int strcmp (const char* str1, const char* str2);
我们可以看到,这个函数的功能是比较两个函数的大小关系,所以对于传进来的字符串并不会对其进行修改,那么我们可以用const 来修饰,然后根据比较的结构返回一个int类型的值
当然,如果str1 > str2 返回的int类型的值是 > 0 的
如果str1 = str2 返回的int类型的值是 == 0 的
如果str1 < str2 返回的int类型的值是 < 0 的
我们可以看到,字符串的比较是比较那个字符串比较大,而不是更长的字符串大。
二,长度受限字符串函数
什么是长度受限字符串函数,就是我们可能控制函数 拷贝。追加和比较的数目
2.1 strncmp
int strncmp(const char* str1, const char* str2, size_t num);这里我们可以看到他和 strcmp的不同在于,他多了一个参数,size_t numsize_t 代表他是无符号整形,因为在字符串函数中我们不会使用负数去衡量一个字符串
![c37428c84f424ac3aa713efb41bf0df7.png](https://img-blog.csdnimg.cn/direct/c37428c84f424ac3aa713efb41bf0df7.png)
![791d55bf445047c196a347a1bcaaef40.png](https://img-blog.csdnimg.cn/direct/791d55bf445047c196a347a1bcaaef40.png)
2.2 strncpy
char* strncpy(char* destination, const char* source, size_t num);
他与strcpy函数是一样的,只是在后面增加了一个,我们需要拷贝多少个字节的功能
![37d475c76d354353a0fe808943cebfe6.png](https://img-blog.csdnimg.cn/direct/37d475c76d354353a0fe808943cebfe6.png)
2.3 strncat
char* strncat(char* destination, const char* source, size_t num);
他和strcat的功能也是一样的,我们可以去限制他去追加多少个字节的源字符串内容到目标字符串内容中去。
我们可以看到,他在str1中追加了 3个字节大小的str2中的内容到str1里面。这里面需要注意的是,这样拷贝可能会使str1中没有 '\0' 因为拷贝的时候没有拷贝'\0' 但是在vs中他自动帮 str1后面的内容初始化为了 0
三,字符串查找函数
char* strstr(const char* str1, const char* str2);
他的功能是在str1中找他的子串看是否于字符串str2相等,如果相等,就返回相等的子字符串的首元素地址。如果没有子字符串于str2相等,就返回 NULL
那么我们来看一下吧
我们可以看到,我们通过strstr找到了str1中的一个子字符串 和str2相等并且返回了这个子字符串的起始地址,然后我们通过起始地址找到了对应的子串,然后修改了他的子串内容。
当然他可能不存在这样的字串,所以我们在拷贝之前,需要判断接收他的指针是否为NULL。
四,strtok
char* strtok(char* str, const char* sep);该函数只做简单的介绍sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
![093a292189b94062b12f874ab95da840.png](https://img-blog.csdnimg.cn/direct/093a292189b94062b12f874ab95da840.png)
![208a0e6902844b43b99cdb8666206297.png](https://img-blog.csdnimg.cn/direct/208a0e6902844b43b99cdb8666206297.png)
![0a4227fa485648a0a086aa669732b0b1.png](https://img-blog.csdnimg.cn/direct/0a4227fa485648a0a086aa669732b0b1.png)
![4fcc3177f74049659ea73659824f3cf9.png](https://img-blog.csdnimg.cn/direct/4fcc3177f74049659ea73659824f3cf9.png)
![792a619c95ed4455a4063d81f426c8dc.png](https://img-blog.csdnimg.cn/direct/792a619c95ed4455a4063d81f426c8dc.png)
五,字符函数的使用及介绍
函数
|
如果他的参数符合下列条件就返回真
|
iscntrl
|
任何控制字符
|
isspace
|
空白字符:空格‘ ’,换页‘\f’,换行'\n',回车‘\r’,制表符'\t'或者垂直制表符'\v'
|
isdigit
|
十进制数字 0~9
|
isxdigit
|
十六进制数字,包括所有十进制数字,小写字母a~f,大写字母A~F
|
islower
|
小写字母a~z
|
isupper
|
大写字母A~Z
|
isalpha
|
字母a~z或A~Z
|
isalnum
|
字母或者数字,a~z,A~Z,0~9
|
ispunct
|
标点符号,任何不属于数字或者字母的图形字符(可打印)
|
isgraph
|
任何图形字符
|
isprint
|
任何可打印字符,包括图形字符和空白字符
|
六,字符串函数的模拟实现
6.1 strlen的模拟实现
int my_strlen(const char* str)
{
int count = 0;
//如果 *str不为'\0' count就加 1;
while (*str++ != '\0')
{
count++;
}
return count;
}
int main()
{
char arr[] = "abcdef";
int ret = my_strlen(arr);
printf("ret = %d",ret);
return 0;
}
6.2 strcpy的模拟实现
#include<stdio.h>
char* my_strcpy(char* destination, const char* source)
{
//因为会改变destination的指向内容,所以保存一下
char* temp = destination;
//如果最后的 *source的值是 '\0' 及为假 while循环终止,每次将*source的值给给*destination之后指针都指向后面的内容
while (*destination++ = *source++)
{
;
}
return temp;
}
int main()
{
char str1[] = "abcdef";
char str2[] = "bcde";
char* ret = my_strcpy(str1,str2);
printf("%s\n", ret);
return 0;
}
6.3 strcat函数的实现
#include<stdio.h>
char* my_strcat(char* destination, const char* source)
{
char* temp = destination;
//判断是否是目标地址 '\0'存放处
while (*destination)
{
destination++;
}
//如果最后的 *source的值是 '\0' 便是为假 while循环终止,每次将*source的值给给*destination之后指针都指向后面的内容
while (*destination++ = *source++)
{
;
}
return temp;
}
int main()
{
char str1[15] = { 'h','e','l', 'l','o' };
char str2[] = "world";
char* ret = my_strcat(str1, str2);
printf("%s", ret);
return 0;
}
6.4 strcmp函数的实现
#include<stdio.h>
int my_strcmp(const char* str1, const char* str2)
{
//循环时,也要判断 str1 和 str2的内容是不是指向了 '\0'
while ((*str1 == *str2) && *str1 && *str2)
{
str1++;
str2++;
}
//返回 *str1 和 *str2 的差值,如果 > 0 就是 str1字符串大于 str2字符串
//如果 < 0 就是 str1字符串 小于 str2字符串
//如果 = 0 就是 str1字符串 等于 str2字符串
return (*str1 - *str2);
}
int main()
{
char str1[] = "abcdef";
char str2[] = "abcdeg";
int ret = my_strcmp(str1, str2);
printf("ret = %d", ret);
return 0;
}