🐵本文将通过函数原型、用法、模拟实现等多个方面全面讲解字符串的库函数
1.strlen📚
1.1函数用法📗
strlen函数用来计算字符串的长度,它会从接收到字符的地址开始读取直到遇到'\0',每读取一个非'\0'的字符长度+1,最后返回一个size_t(无符号)类型的数
strlen函数原型:
返回类型为size_t,参数是一个字符指针用来接收字符的地址
1.2具体实现📕
#include<stdio.h>
#include<string.h> //记得加上头文件int main()
{char arr[] = "abcedf";size_t len = strlen(arr);printf("%zd", len); //结果为6return 0;
}
1.3模拟实现📘
这里总结了三种strlen函数模拟实现的方法,分别为:计数器、指针-指针和递归
计数器:
size_t my_strlen1(const char* arr) //计数器
{size_t count = 0;while (*arr++ != '\0'){count++;}return count;
}
递归:
size_t my_strlen(const char* arr)
{if (*arr != '\0'){return 1 + my_strlen(++arr);}else{return 0;}
}
每次递归都判断以下arr指针是否指向'\0',如果是则返回0,不是则指向下一个字符进行判断并且长度+1
指针-指针:
size_t my_strlen2(const char* arr)
{char* p = arr;while (*arr != '\0'){arr++;}return arr - p;
}
指针-指针用来计算两个指针之间元素的个数,先让p指向字符串的首地址,之后通过while循环使arr指向'\0',最后返回arr - p
2.strcpy📚
2.1函数用法📗
strcpy函数用来拷贝字符串将源数组中的字符串拷贝到目标数组中,但需要注意以下几点:
- 目标数组可能没有'\0',所以strcpy再拷贝时会将源数组的'\0'也拷贝过去,也就是说源数组中必须有'\0'
- 目标数组的空间必须足够大,确保其在被拷贝后能存放的下字符串
- 目标数组必须可变,不能是常量字符串
strcpy函数原型:
返回类型为char*,destination用来接收目标数组的地址,source用来接收源数组的地址
2.2具体实现📕
#include<stdio.h>
#include<string.h>int main()
{char arr1[20] = { 0 }; //目标数组空间确保能存放源数组char arr2[] = "abcdef";strcpy(arr1, arr2);printf("%s", arr1); //结果为abcdefreturn 0;
}
2.3模拟实现📘
#include <stdio.h>
#include<assert.h>char* my_strcpy( char* des, const char*src)
{assert(des && src); //断言判断des和src是否时空指针char* ret = des; //将des的首地址赋给ret用来最后返回,因为des在++后不再指向首地址while (*des++ = *src++) //依次将字符赋给des直到'\0'循环终止{;}return ret;
}int main()
{char arr1[] = "abcdef";char arr2[20] = { 0 };char* ret = my_strcpy(arr2, arr1);printf("%s", ret);return 0;
}
3.strcat📚
3.1函数用法📗
strcat函数用来追加字符串,将源数组加到目标数组的末尾,即从目标数组的'\0'位置处开始追加;和strcpy函数需要注意的点一样:
- 源数组必须有'\0'
- 目标数组的空间必须足够大
- 目标数组必须可变,不能是常量字符串
strcat函数原型:
返回类型为char*,destination用来接收目标数组的地址,source用来接收源数组的地址
3.2具体实现📕
#include<stdio.h>
#include<string.h>int main()
{char arr1[20] = "abc"; //目标空间必须足够大char arr2[] = "def";strcat(arr1, arr2);printf("%s", arr1); //结果为abcdefreturn 0;
}
3.3模拟实现📘
#include<stdio.h>
#include<assert.h>char* my_strcat(char* des, const char* src)
{assert(des && src); //断言判断des和src是否为空指针char* ret = des;while (*des != '\0') //先找到目标数组'\0'的位置{des++;}while (*des++ = *src++) //从目标数组的'\0'位置处开始依次将源数组拷贝到目标数组{;}return ret;
}int main()
{char arr1[20] = "abc";char arr2[] = "def";char* ret = my_strcat(arr1, arr2);printf("%s", ret);return 0;
}
4.strcmp📚
4.1函数用法📗
strcmp函数用来比较字符串,从两个字符串的第一个字符开始依次比较它们的ASCII码值,只要出现一个字符大于另一个字符就停止比较,此时较大字符所在的字符串大于另一个字符串
strcmp函数原型:
str1和str2分别接收要比较的两个数组的地址,返回类型为int,str1>str2则返回一个大于0的数,str1<str2则返回一个小于0的数,str1=str2则返回0
4.2具体实现📕
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = "abcfff";char arr2[] = "abczz";int cmp = my_strcmp(arr1, arr2);if (cmp > 0){printf(">"); }else {printf("<="); //结果为<=,因为f<z}return 0;
}
4.3模拟实现📘
#include<stdio.h>
#include<assert.h>int my_strcmp(const char* str1, const char* str2)
{assert(str1 && str2);while (*str1++ == *str2++) //依次比较两字符串的字符{if (*str1 == '\0' && *str2 == '\0'){return 0; //若两字符串的字符一直到'\0'都相等,则相等,返回0}}return *str1 - *str2; //*str1大返回大于0的数,否则返回小于0的数
}int main()
{char arr1[] = "abcfff";char arr2[] = "abczz";int cmp = my_strcmp(arr1, arr2);if (cmp > 0){printf(">");}else{printf("<=");}return 0;
}
5.strncpy📚
5.1函数用法📗
strncpy函数原型:
这里相较于strcpy多了一个参数num
用法:和strcpy用法相同,但它是将源数组的前num个字符拷贝到目标数组中
5.2具体实现📕
#include<stdio.h>int main()
{char arr1[] = "abcdef";char arr2[20] = { 0 };size_t num = 3;strncpy(arr2, arr1, num); //将arr1的前三个字符拷贝到arr2中printf("%s", arr2); //结果为abcreturn 0;
}
5.3模拟实现📘
和strcpy的模拟实现类似,只不过要加一条对n的判断以确保只拷贝前n个字符
#include<stdio.h>
#include<assert.h>char* my_strncpy(char* des, const char* src, size_t n)
{assert(des && src);char* ret = des;while (*des++ = *src++){n--;if (n == 0) {return ret;}}
}int main()
{char arr1[] = "abcedf";char arr2[20] = { 0 };size_t num = 3;char* r = my_strncpy(arr2, arr1, num);printf("%s", r);return 0;
}
6.strncat📚
6.1函数用法📗
strncat函数原型:
用法:和strncat函数用法相同,但它是将数组的前num个字符追加到目标数组的'\0'处
6.2具体实现📕
#include<stdio.h>
#include<string.h>int main()
{char arr1[20] = "abc\0xxx";char arr2[] = "defghi";size_t num = 3;strncat(arr1, arr2, num); //加完后会自动将\0加上printf("%s", arr1);return 0;
}
在arr1的'\0'处将def加上后会自动加一个'\0'以构成一个完整的字符串
6.2模拟实现📘
和strcat的模拟实现类似,只不过要加一条对n的判断以确保只追加前n个字符
#include<stdio.h>
#include<assert.h>char* my_strncat(char* des, const char* src, size_t n)
{char* ret = des;while (*des != '\0'){des++;}while (*des++ = *src++){n--;if (n == 0){*des = '\0';return ret;}}
}int main()
{char arr1[20] = "abc";char arr2[] = "defghi";size_t num = 3;char* ret = my_strncat(arr1, arr2, num);printf("%s", ret);return 0;
}
7.strncmp📚
7.1函数用法📗
strncmp函数原型:
用法:和strcmp用法相同,但它只比较两个字符串前num个字符
7.1具体实现📕
#include<stdio.h>
#include<string.h>int main()
{char arr1[] = "abcdef";char arr2[] = "abcdzz";size_t num = 0;int cmp = strncmp(arr1, arr2, num);if (cmp > 0){printf(">");}else{printf("<=");}return 0;
}
7.3模拟实现📘
#include<stdio.h>
#include<assert.h>int my_strncmp(const char* str1, const char* str2, size_t n)
{assert(str1 && str2);while (*str1 == *str2){n--;if (n == 0){return 0; //当前n个字符相同,返回0}}return *str1 - *str2; //出现字符不相同时,跳出上面循环,返回*str1 - *str2
//前者大,返回大于0的值,后者大,返回小于0的值}int main()
{char arr1[] = "abcdef";char arr2[] = "abcdzz";size_t num = 3;int cmp = my_strncmp(arr1, arr2, num);if (cmp > 0){printf(">");}else{printf("<=");}return 0;
}
🙉以上为7个字符串库函数的讲解,后续会对剩余的字符串库函数和内存函数进行讲解