目录
长度不受限制的字符串 strcpy strcat strcmp 关注\0
长度受限制的字符串 strncy,strncat,strncmp
一、strlen
1.1strlen函数的认识
strlen是求字符串长度的
使用的时候要引入头文件
#include<stdio.h>
strlen函数的使用
#include<stdio.h>
#include<string.h>
int main()
{
if (strlen("abc") > strlen("abcdef"))
{
printf("大于\n");
}
else
{
printf("小于等于\n");
}
return 0;
}
注意:
- 字符串以 '\0' 作为结束标志,strlen函数返回的是在字符串中 '\0' 前面出现的字符个数(不包含 '\0' )
- 参数指向的字符串必须要以 '\0' 结束
- 函数的返回值为size_t,是无符号的
1.2 strlen 函数的模拟实现
1.计数器方式
2.递归
int my_strlen(const char* p)
{
if ((*p) != '\0')
{
return 1 + my_strlen(p+1);
}
return 0;
}
int main()
{
char arr[] = "abcdef";
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
3.指针- 指针
int my_strlen(const char* p)
{
char* start = p;
while ((*p) != '\0')
{
p++;
}
return p - start;
}
int main()
{
char arr[] = "abcdef";
int ret = my_strlen(arr);
printf("%d\n", ret);
return 0;
}
二、strcpy
长度不受限制的字符串 strcpy strcat strcmp 关注\0
2.1 strcpy函数的认识
strcpy函数的功能:拷贝字符串 将源头(source)的字符串拷贝到目标字符串的空间(destination)
使用strlcpy函数要引头文件
#include<string.h>
注意:
- 源字符串必须以 '\0' 结束,没有 ‘\0’拷贝无法停止
- 目标空间必须有足够的大,能容纳下源字符串的内容
- const修饰源字符串,使源字符串不能被修改
- 目标空间必须可修改
- 拷贝字符串时,‘\0’也会被拷贝
strcpy 函数的使用
2.2 strcpy函数的模拟实现
源代码
2.优化后
要返回目的空间的地址,后续操作中dest的地址被改变,所以提前创建一个变量
对指针解引用操作,要保证指针的有效性,所以要加assert断言
三、strcat
3.1 stract函数的认识
strcat函数的功能:追加字符串 将源头(source)的字符串连接到目标(destination)字符串的后面
使用strcat函数要引头文件
#include <string.h>
注意:
- 源字符串和目标字符串必须以 '\0' 结束
- 目标空间必须有足够的大,能容纳下源字符串的内容
- 目标空间必须可修改
- 目的地和来源不得重叠
- 不能自己给自己追加
strcat函数的使用
3.2 strcat函数的模拟实现
3.3 strcat 字符串自己给自己追加,如何?(不行)
四、strcmp
4.1 strcmp 函数的认识
strcmp函数的功能:比较两个字符串的大小
比较对应字符的大小,相等时比较下一对,直到大小不相等或都遇到'\0'停止
使用strlcat函数要引头文件
#include <string.h>
strcmp的使用:
4.2 strcmp函数的模拟实现
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
int main()
{
int ret =my_strcmp("bbq", "bcq");
printf("%d", ret);
}
同理也可以这样写:
因为只规定了>0,<0,=0的数字 没有规定一定要返回1和-1,所以可以做差
在vs编辑器下面:> 返回 1
< 返回 -1
= 返回 0
五、strncpy
长度受限制的字符串 strncy,strncat,strncmp
5.1 strncpy函数的认识
strncpy函数相较于strcmp函数多了一个参数size_t num (长度的限制)
strncpy函数的功能:拷贝num个字符从源字符串到目标空间
使用strncpy函数要引头文件
#include <string.h>
注意:
- 如果源字符串的长度小于num,则拷贝完源字符串之后,在目标的后边追加0,直到num个
5.2strncpy函数的模拟实现
六、strncat
6.1 strncat函数的认识
strncat函数的功能:把源头(source)的num个字符连接到目标(destination)字符串的后面 (追加)
长度再长也是把串里面内容 追加完 把我的内容包括\0拷贝进去就行
注意:
源字符串中有几个就追加几个,多余的不会补\0
6.2 strncpy函数的模拟实现
#include<stdio.h>
#include<string.h>
#include <assert.h>
char* my_strncat(char* dest, const char* src, int num)
{
assert(dest && src);
char* s = dest;
while (*dest)
{
dest++;
}
while (num--)
{
*dest++ = *src++;
}
return s;
}
int main()
{
char arr1[20] = "hello ";
char arr2[] = "worldabcde";
printf("%s\n", my_strncat(arr1, arr2, 4));
return 0;
}
七、strncmp
7.1 strncmp函数的认识
strncmp函数的功能:比较前num个字符的大小
使用strncmp函数要引头文件
#include <string.h>
strncmp函数的使用
7.2 strncmp函数的模拟实现
#include<stdio.h>
#include<string.h>
#include <assert.h>
int my_strncmp(char* dest, const char* src, int num)
{
int ret = 0;
assert(dest != NULL);
assert(src != NULL);
while (!(ret = *(unsigned char*)src - *(unsigned char*)dest) && *dest)
{
++dest;
++src;
}
if (ret < 0)
{
ret = 1;
}
else if (ret > 0)
{
ret = -1;
}
return ret;
}
int main()
{
char arr1[20] = "abcdfq";
char arr2[] = "abcg";
printf("%d\n", my_strncmp(arr1, arr2, 4));
return 0;
}
八、strstr
8.1 strstr函数的认识
strstr函数的功能:在str1中找str2第一次出现的位置
使用strstr函数要引头文件
#include <string.h>
strstr函数的使用
8.2 strstr函数的模拟实现
九、strtok
strtok函数函数的功能:将字符串拆分为标记
strtok函数的使用:
注意:
sep参数是个字符串,定义了用作分隔符的字符集合
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标 记
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注: strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容 并且可修改)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串 中的位置
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记
如果字符串中不存在更多的标记,则返回 NULL 指针
九、strerror
9.1 strerror函数的认识
strerror函数的功能:返回错误码,所对应的错误信息
使用strerror函数要引头文件
#include <erron.h>
库函数在执行的时候,发生了错误,会将一个错误码放在error这个变量中,errno是C语言中提供的一个全局变量
9.2 streeor函数的使用
十.字符分类函数
使用字符判断函数要引头文件
#include <ctype.h>
判断为真返回非0的数,判断为假返回0
函数
| 如果他的参数符合下列条件就返回真 |
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
|
任何可打印字符,包括图形字符和空白字符
|
十一、字符转换函数
int tolower ( int c ); 大写--->小写
int toupper ( int c ); 小写--->大写
十二、memcpy
12.1 memcpy函数的认识
memcpy函数的功能:将字节数的值从源指向的位置直接复制到目标指向的内存块
void* 指针可以接受任意类型的数据
函数拷贝结束后返回目标空间的起始地址
memcpy函数是用来处理不重叠的内存拷贝的
- 函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
- 这个函数在遇到 '\0' 的时候并不会停下来。
- 如果source和destination有任何的重叠,复制的结果都是未定义的。
12.2 memcpy函数的模拟实现
#include <stdio.h>
#include <string.h>
#include <assert.h>
void* my_memcpy(void* dest, const void* src, int num)
{
assert(dest && src);
void* ret = dest;
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return ret;
}
int main()
{
int arr1[5] = { 0 };
int arr2[] = { 1,2,3 };
my_memcpy(arr1, arr2, 12);
int i = 0;
for (i = 0; i < 5; i++)
{
printf("%d ", arr1[i]);
}
}
12.3 memcpy函数是用来处理不重叠的内存拷贝的
![](https://i-blog.csdnimg.cn/blog_migrate/0de959d0d4c22bafecf6c8a1d67f5768.png)
十三、memmove
13.1 memmove函数的认识
memmove函数的功能:将字节数的值从源指向的位置复制到目标指向的内存块。允许目标和源重叠
注意:
为避免溢出,目标参数和源参数指向的数组的大小应至少为字节数
如果源空间和目标空间出现重叠,就得使用memmove函数处理
使用memmove函数要引头文件
#include <string.h>
![](https://i-blog.csdnimg.cn/blog_migrate/81ba0a403ad4d701fa794bac7debf50c.png)
13. 2 memmove 函数的模拟实现
void* my_memmove(void* dest, const void* src, size_t num)
{
void* ret = dest;
assert(dest && src);
if (dest < src)
{
//前->后
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
//后->前
while (num--)//20
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
// 1 2 1 2 3 4 5 8 9 10
my_memmove(arr1+2, arr1, 20);
int i = 0;
for (i = 0; i < 10; i++)
{
printf("%d ", arr1[i]);
}
return 0;
}
十四、memcmp
14.1 memcmp函数的认识
使用memcmp函数要引头文件
#include <string.h>
两个数组的前九个字节是都是相同的,,所以返回0
memcmp函数的使用
14.2 memcmp函数的模拟实现
int my_memcmp(const void* s1, const void* s2, int num)
{
assert(s1 && s2);
char* str1 = (char*)s1;
char* str2 = (char*)s2;
int i = 0;
for (i = 0; i < num; i++)
{
if (*(str1 + i) != *(str2 + i))
{
return (*(str1 + i) - *(str2 + i));
}
}
return 0;
}
int main()
{
int arr1[] = { 1,2,1,4,5,6 };
int arr2[] = { 1,2,257 };
int ret = my_memcmp(arr1, arr2, 9);
printf("%d\n", ret);
return 0;
}
十五、memset
15.1 memset函数的认识
memset函数的功能:把ptr指向的前num个字节设置为value值
memset 内存设置 字节为单位,把所有的字节设成同一个值
使用memcset函数要引头文件
#include <string.h>
memset函数的使用
注意:
- 要设置的值。该值作为 int 传递,但该函数使用此值的无符号char转换填充内存块
- 以字节为单位来设置