目录
前言
一、函数介绍及其模拟实现
1.strlen
(1)函数头部
(2)注意事项
+
(3)strlen的使用
#include<stdio.h>
#include<string.h>
int main()
{
char* str = "abcef";
int len = strlen(str);//获取字符串的长度
printf("%d",len);
return 0;
}
(4)strlen的模拟实现
//普通实现
#include<stdio.h>
int my_strlen(char *str)
{
int count = 0;
while (*str++)
count++;
return count;
}
int main()
{
char* str = "abcdef";
int len = my_strlen(str);
printf("%d",len);
return 0;
}
//链式访问实现
#include<stdio.h>
int my_strlen(char *str)
{
int count = 0;
while (*str++)
count++;
return count;
}
int main()
{
char* str = "abcdef";
printf("%d",my_strlen(str));//链式访问
return 0;
}
//函数递归实现
#include<stdio.h>
int my_strlen(char* str)
{
if (*str == '\0')
return 0;
else
return (1 + my_strlen(str + 1));
}
int main()
{
char* str = "abcdef";
int len = my_strlen(str);
printf("%d",len);
return 0;
}
//指针-指针实现
//指针- 指针
#include<stdio.h>
int my_strlen(char*str)
{
char* end = str;
while (*end)
end++;
return end - str;
}
int main()
{
char* str = "abcdef";
int len = my_strlen(str);
printf("%d",len);
return 0;
}
2.strcpy
(1)函数头部
(2)注意事项
(3)strcpy的使用
#include<stdio.h>
#include<string.h>
int main()
{
char str1[20] = {0};
char* str2 = "abcdef";
strcpy(str1,str2);
printf("%s",str1);
return 0;
}
- (4)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;
}
int main()
{
char str1[20] = { 0 };
char* str2 = "abcdef";
printf("%s", my_strcpy(str1, str2));
return 0;
}
3.strcat
(1)函数头部
(2)注意事项
(3)strcat的使用
//strcat的使用
#include<stdio.h>
#include<string.h>
int main()
{
char str1[20] = "abcdef";
char* str2 = "112233";
strcat(str1,str2);
printf("%s",str1);
return 0;
}
(4)strcat的模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strcat(char*dest,const char*src)
{
char* ret = dest;
while (*dest)
dest++;
while (*dest++ = *src++)
;
return ret;
}
int main()
{
char str1[20] = "abcdef";
char* str2 = "112233";
my_strcat(str1, str2);
printf("%s", str1);
return 0;
}
4.strcmp
(1)函数头部
(2)注意事项
(3)strcmp的使用
#include<stdio.h>
#include<string.h>
int main()
{
char* str1 = "abcdef";
char* str2 = "aaaaaa";
int ret = strcmp(str1,str2);//可以知道 str1>str2
printf("%d",ret);//编译器返回一个大于0的数字
return 0;
}
(4)strcmp的模拟实现
#include<stdio.h>
#include<assert.h>
int my_strcmp(const char*str1,const char*str2)
{
assert(str1&&str2);
while (*str1 == *str2)
{
if (*str1 == '\0')
return 0;
str1++;
str2++;
}
return (*str1 - *str2);
}
int main()
{
char* str1 = "abcdef";
char* str2 = "aaaaaa";
int ret = my_strcmp(str1, str2);
printf("%d", ret);
return 0;
}
我们发现上述字符串函数 的字符串长度不受到限制
接下来介绍几个长度受到限制的字符串函数
5.strncpy
(1)函数头部
(2)注意事项
(3)strncpy的使用
#include<stdio.h>
#include<string.h>
int main()
{
char str1[20] = "aa";
char str2[] = "bbb";
strncpy(str1,str2,5);
printf("%s",str1);
return 0;
}
接下来我们一下调试的内容
6.strncat
(1)函数头部
(2)注意事项
(3)strncat的使用
//strncat的使用
#include<stdio.h>
#include<string.h>
int main()
{
char str1[20] = "aaa";
char* str2 = "bbc";
strncat(str1,str2,3);
printf("%s",str1);
return 0;
}
7.strncmp
(1)函数头部
(2)注意事项
< 0 不匹配的第一个字符在 str1 中的值低于 str2 中的值
0 两个字符串的内容相等
>0 第一个不匹配的字符在str1中的值比在str2中的值大
(3) strncmp的使用
//strncmp的使用
#include<stdio.h>
#include<string.h>
int main()
{
char* str1 = "aaab";
char* str2 = "abba";
int len = strncmp(str1,str2,2);//比较前两个字符
printf("%d",len);
return 0;
}
8.strstr
(1)函数头部
(2)注意事项
(3)strstr的使用
#include<stdio.h>
#include<string.h>
int main()
{
char* str1 = "abcxaxad";
char* str2 = "xax";
char* ret = strstr(str1,str2);
printf("%s",ret);
return 0;
}
(4)strstr模拟实现
//strstr的模拟实现
#include<stdio.h>
#include<assert.h>
char* my_strstr(const char* str1,const char* str2)
{
assert(str1&&str2);
char* cp = str1;
char* p1 = str1;
char* p2 = str2;
while (cp)
{
p1 = cp;//从cp指向的字符开始
p2 = str2;//从子串的首字符开始
while (*p1 == *p2 && *p1 && *p2)
{
p1++;
p2++;
}
if (*p2 == '\0')
return cp;
cp++;
}
return NULL;
}
int main()
{
char* str1 = "abcxaxad";
char* str2 = "xax";
char* ret = my_strstr(str1,str2);
printf("%s",ret);
return 0;
}
图解:
起始情况
找到的时候
9.strtok
(1)函数头部
(2)注意事项
(3)strtok的使用 ( 把字符串根据 分隔符 分隔开来)
#include<stdio.h>
#include<string.h>
int main()
{
char* p = "aabbcc@112233.abc";
const char* sep = "@.";
char arr[30];
char* str = NULL;
strcpy(arr,p);//临时拷贝字符串
for (str = strtok(arr, sep); str != NULL; str = strtok(NULL, sep))
printf("%s\n",str);
return 0;
}
10.strerror
返回错误码,所对应的错误信息(这里是程序运行时的错误)
在介绍其他知识:库函数在执行时,发生了错误,会将一个错误码存到errno这个变量中(全局变量)
(1)函数头部
(2)strerror的使用
#include<stdio.h>
#include<string.h>
#include<errno.h>
int main()
{
int i = 0;
for (i = 0; i < 10;i++)
{
printf("%d is %s\n",i,strerror(i));//打印错误码 0到9的错误信息
}
}
11.其他字符串函数
iscntr | 任何控制字符 |
isspace | 空白字符: 空格 ' ',换页 ‘\f,换行 '\n',回车 '\r' ,制表符 ‘\t’,垂直制表符 ‘\v’ |
isdigit | 十进制数字 0 - 9 |
isxdigit | 十六进制数字 0 - 9 ,a - f |
islower | 小写字母 a- z |
isupper | 大写字母 A - Z |
isalpha | 字母 a - z , A - Z |
isalnum | 字母或者数字 a - z , A - Z,0 - 9 |
ispunct | 标点符号,任何不属于字母和数字的图形字符 |
isgragh | 任何图形字符 |
isprint | 可以打印任何字符 |
根据上述字符函数,【例如】islower(a) 如果圆括里面的是小写字母,该函数就返回真。
二、内存函数
1.memcpy
(1)函数头部
(2)注意事项
(3)memcp的使用
#include<stdio.h>
#include<string.h>
int main()
{
int arr1[] = {1,2,3,4,5};
int arr2[20] = {0};
//将arr1中的内容拷贝到arr2中
memcpy(arr2,arr1,20);
int i = 0;
for (i = 0; i < 20;i++)
{
printf("%d ",arr2[i]);
}
return 0;
}
(4)memcpy的模拟使用
//memcpy的模拟实现
#include<stdio.h>
#include<assert.h>
void* my_memcpy(void* dest, const void *src ,size_t count)
{
assert(dest && src);
void* ret = dest;
while (count--)//count表示的是字节的个数
{
//因为char类型是占一个字节
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
return dest;
}
int main()
{
int arr1[] = { 1,2,3,4,5,6,7,8,9,10 };
int arr2[20] = {0};
my_memcpy(arr2,arr1,40);
int i = 0;
for (i = 0; i < 20;i++)
{
printf("%d ",arr2[i]);
}
return 0;
}
2.memove
(1)函数头部
(2)注意事项
(3)memmove的使用
#include<stdio.h>
#include<string.h>
int main()
{
//这里我们给str自己拷贝一个123
char str[] = "web online 123";
memmove(str, str + 11,3);//可以用于重叠内存拷贝
printf("%s",str);
return 0;
}
(4)memmove的模拟实现
//memmove的模拟实现
#include<stdio.h>
#include<assert.h>
void* my_memmove(void* dest,const void* src,size_t num)
{
assert(dest&&src);
void* ret = dest;
//当地址src 小于 dest的时候
if (dest < src)
{
//这里我们src从前到后移动
//前->后
while (num--)
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (num--)
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
int main()
{
int arr1[] = {1,2,3,4,5,6,7,8,9,10};
my_memmove(arr1, arr1 + 2,12);//前->后
//my_memmove(arr1+5,arr1+2,12);//后->前
int i = 0;
for (i = 0; i < 10;i++)
{
printf("%d ",arr1[i]);
}
return 0;
}
前->后
后->前
情况1
情况2
3.memcmp
(1)函数头部
(2)注意事项
(3)memcmp的使用
//memcmp的使用
#include<stdio.h>
#include<string.h>
int main()
{
char buf1[] = "aabbcc2210";
char buf2[] = "aabbcc2211";
int n = 0;
n = memcmp(buf1,buf2,sizeof(buf1));
if (n > 0)
printf("buf1大于buf2");
else if (n < 0)
printf("buf1小于buf2");
else
printf("buf1等于buf2");
return 0;
}