湖南汉泰建设有限公司网站,宿迁网络推广公司,网站开发与软件开发的区别,西班牙网站后缀字符函数和字符串函数 前期背景求字符串长度函数strlen函数strlen函数三种模拟实现 长度不受限制的字符串函数strcpy函数strcpy函数模拟实现strcat函数strcat函数模拟实现strcmp函数strcmp函数模拟实现 长度受限制的字符串函数strncpy函数strncpy函数模拟实现strncat函数strnca… 字符函数和字符串函数 前期背景求字符串长度函数strlen函数strlen函数三种模拟实现 长度不受限制的字符串函数strcpy函数strcpy函数模拟实现strcat函数strcat函数模拟实现strcmp函数strcmp函数模拟实现 长度受限制的字符串函数strncpy函数strncpy函数模拟实现strncat函数strncat函数模拟实现strncmp函数strncmp函数模拟实现 字符串查找strstr函数strstr函数模拟实现strtok函数 错误信息报告strerror函数perror函数字符分类函数大小写转化函数 内存操作函数memcpy函数memcpy函数模拟实现memmove函数memmove函数模拟实现memset函数memcmp函数 铁汁们今天给大家分享一篇字符函数和字符串函数全面知识总结来吧开造⛳️ 前期背景
在C语言具有许多数据类型但不具有字符串类型字符串通常放在字符指针或字符数组中因为在C语言中对字符和字符串的处理很频繁从而延伸出许许多多有关字符串的函数。
求字符串长度函数
strlen函数
功能求字符串中元素的个数不包括末尾的 ’ \0 。 头文件为#includestring.h。 字符串是以 ’ \0 作为结束标志strlen函数返回的是在字符串中 ’ \0 前面的总元素个数不包括 ’ \0 ) 。
注意 1.strlen函数的返回值为 size_t ,无符号整形unsigned int。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{const char* str1 abcdef; //元素个数为6个const char* str2 bbb; //元素个数为3个if (strlen(str2) - strlen(str1) 0) //两个无符号进行运算则结果也为无符号{printf(str2str1\n);}else{printf(srt1str2\n);}return 0;
}图解
2.参数指向的字符串必须要以 ‘\0’ 为结束标志否则strlen会越界一直找’ \0 ,直到遇到 ’ \0 ’ 停止结果为随机值。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{char arr1[8] abcde;char arr2[5] {a,b,c,d,e};printf(%d\n,strlen(arr1));printf(%d\n,strlen(arr2));return 0;
}strlen函数三种模拟实现
1.计数器
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
int my_strlen(const char* arr) //计数器模拟实现strlen
{assert(arr); //断言检查指针的有效性防止对空指针进行解引用、加减整数操作int count 0;while (*arr){count;arr;}return count;
}int main()
{char arr[10] hello bit;int len my_strlen(arr);printf(%d\n, len);return 0;
}2.指针-指针计算的是两指针之间的元素个数
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
int my_strlen(const char* arr) //指针-指针模拟实现strlen
{assert(arr); //断言检查指针的有效性防止对空指针进行解引用、加减整数操作char* start arr;char* end arr;while (*end)end;return end - start;
}int main()
{char arr[10] hello bit;int len my_strlen(arr);printf(%d\n, len);return 0;
}3.递归
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
int my_strlen(const char* arr) //递归模拟实现strlen
{assert(arr); //断言检查指针的有效性防止对空指针进行解引用、加减整数操作if (*arr ! \0)return my_strlen(arr 1) 1;elsereturn 0;
}int main()
{char arr[10] hello bit;int len my_strlen(arr);printf(%d\n, len);return 0;
}长度不受限制的字符串函数
strcpy函数
功能将源头字符串的内容拷贝到目标字符串包括末尾的 ‘\0’相当于从前往后进行覆盖。 头文件为#includestring.h。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{char dest[20] abcdefg;char source[6] hello;strcpy(dest, source 2); //可以从源字符串的任意位置处开始拷贝printf(%s, dest);return 0;
}注意 1.会将源头字符串的 \0’拷贝进去。 2.目标空间要足够大足以存放源头字符串。 3.目标空间必须是可变的不能被const修饰。 4.源头字符串必须以 ‘\0’ 为结束标志因为strcpy拷贝完\0’后就立即停止拷贝。 strcpy函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
#includeassert.h
char* my_strcpy(char* dest, const char* source)
{assert(destsource); //断言检查指针的有效性防止对空指针进行解引用、加减整数操作char* ret dest;while (*dest *source){;}return ret;
}int main()
{char dest[20] abcdefg;char source[6] hello;char* ret my_strcpy(dest, source);printf(%s, ret);return 0;
}strcpy在内存中的拷贝过程:
strcat函数
功能将源头字符串的内容追加到目标字符串的后面从目标串的’\0’位置开始向后追加。 头文件为#includestring.h。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{char dest[30] heihei;char source[] hello;strcat(dest, source);printf(%s, dest);return 0;
}注意 1.目标字符串必须可修改。 2.源字符串必须含有 \0’为结束标志。 3.目标空间要足够大足以容纳源头字符串的内容。 问题字符串是否可以自己给自己追加 答字符串不可以自己给自己追加因为源头字符串的’\0’会被覆盖造成源头字符串会一直向后死循环追加。strcat遇到源头字符串的 ‘\0’就停止追加并且源头字符串末尾的’\0’也会被追加过去。 strcat函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
char* my_strcat(char* dest,const char* source)
{assert(destsource); //断言检查指针的有效性防止对空指针进行解引用、加减整数操作char* ret dest;while (*dest) //找目标字符串中的\0{dest;}while (*dest *source){;}return ret;
}int main()
{char dest[30] abcde;char source[] hello bit;char* ret my_strcat(dest, source);printf(%s, ret);return 0;
}strcmp函数
功能用来比较两字符串的大小两字符串不能直接用进行比较。 头文件为#includestring.h。 #define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{char s1[] abcdefg;char s2[] abcde;int retstrcmp(s1, s2);printf(%d\n, ret);return 0;
}问题strcmp如何判断两字符串大小
答:两个字符串从前向后依次比较两个字符判断是否相等相等则继续比较下一个字符直到有一个串遇到’\0’并比较完’\0’就停止。若不相等比较两字符的ASCII值ASCII值大的串字符串大。《—等价于—》ASCII值的比较 strcmp返回值三种情况
a.字符串1前面的参数大于 字符串2后面的参数则返回大于0的数。
b.字符串1前面的参数小于 字符串2后面的参数则返回小于0的数。
c.字符串1前面的参数等于 字符串2后面的参数则返回等于0的数。
strcmp函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
int my_strcmp(const char* s1, const char* s2)
{assert(s1 s2);while (*s1 *s2){if (*s1 \0)return 0;s1;s2;}return *s1 - *s2;
}int main()
{char s1[] abcde;char s2[] abcdef;int ret my_strcmp(s1, s2);printf(%d, ret);return 0;
}长度受限制的字符串函数
strncpy函数
功能 头文件为#includestring.h。
情况1源字符串的长度num,将源字符串的前num个字符拷贝到目标字符串中
情况2源字符串的长度num将源字符串全部拷贝到目标字符串中包括源字符串末尾的’\0’源字符串拷贝完后在目标字符串的后面一直追加 ‘\0’,直到num停止。 情况1代码
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{int num 5; //源字符串的长度numchar dest[30] heheabcd;char source[] lala hello;strncpy(dest, source, num);printf(%s, dest);return 0;
}情况2代码
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{int num 20; //源字符串的长度numchar dest[30] heheabcdefghi;char source[] lala hello;strncpy(dest, source, num);printf(%s, dest);return 0;
}内存图
strncpy函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
char* my_strncpy(char* dest,const char* source, int num)
{assert(dest source);char* ret dest;while (num--){if (*source ! \0) //情况1,源字符串的长度num*dest *source;else //情况2源字符串的长度num,源字符串拷贝完后在目标字符串后一直追加\0*dest \0;}return ret;
}int main()
{int num 5;char dest[30] heheabcdefghi;char source[] lala hello;char* ret my_strncpy(dest, source, num);printf(%s\n, dest);return 0;
}strncat函数
功能 头文件为#includestring.h。 情况1源字符串的长度num,将源字符串的前num个字符追加到目标字符串后面最后在目标字符串后面自动补上 ‘\0’
情况2源字符串的长度num将源字符串全部追加到目标字符串后面包括源字符串末尾的’\0’则就停止追加。
情况1代码
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
#includestring.h
int main()
{int num 5; //情况1源字符串的长度numchar dest[30] abcde\0lalalalalala;char source[] hello world;strncat(dest, source, num); printf(%s\n, dest);return 0;
}情况2代码
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
#includestring.h
int main()
{int num 20; //情况2源字符串的长度numchar dest[30] abcde\0lalalalalalalalalalala;char source[] hello world;strncat(dest, source, num);printf(%s\n, dest);return 0;
}strncat函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
char* my_strncat(char* dest, const char* source,int num)
{assert(dest source);char* ret dest;while (*dest)dest;while (num--){*dest *source;if (*source \0) //清款2break;dest;source;}if (*source ! \0) //情况1*dest \0;return ret;
}int main()
{int num 5;char dest[30] abcde\0lalalalalalalalalalala;char source[] hello world;char* retmy_strncat(dest, source, num);printf(%s\n, ret);return 0;
}strncmp函数
功能比较前num个字符的大小 头文件为#includestring.h。
比较到在num范围内有一个串结束、两串中有一个字符不相等前num个字符全部比完就停止比较了。 返回值三种情况同strcmp函数返回值情况相同。
strncmp函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
int my_strncmp(const char* s1,const char* s2, int num)
{assert(s1s2);while (num--){while (*s1 *s2){if(*s1 \0)return 0;s1;s2;}return *s1-*s2;}
}int main()
{int num 3;char arr1[] abcdef;char arr2[] abed;int len my_strncmp(arr1, arr2,num);printf(%d\n, len);return 0;
}字符串查找
strstr函数
功能在string指向的字符串中查找strCharSet指向的字符串是否出现出现则返回strCharSet指向的字符串在tring指向的字符串第一次出现的起始位置若未出现则返回NULL。 头文件为#includestring.h。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
#includestring.h
int main()
{char arr[] abcdefbcdef;char src[] bcdef;char* retstrstr(arr, src);printf(%s\n, ret);return 0;
}strstr函数模拟实现
版本1
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
char* my_strstr(char* dest, char* src)
{assert(dest src);char* cur dest;char* s1;char* s2;while (*cur){s1 cur;s2 src;while (*s2*s1){if (*s1 ! *s2)break;s1;s2;}if (*s2 \0)return cur;cur;}
}int main()
{char arr[] abbbcdefbcdef;char src[] bcdef;char* retmy_strstr(arr, src);printf(%s\n, ret);return 0;
}版本2枚举法效率更高
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
#includestring.h
char* my_strstr(char* dest, char* src)
{assert(dest src);char* ret dest;int len1 strlen(dest);int len2 strlen(src);int i0;for ( ; i len2 len1; i){int j 0;for (; j len2; j){if (dest[ij] ! src[j])break;}if (j len2)return (ret i);}return NULL;
}int main()
{char arr[] abbbcdefbcdef;char src[] bcdef;char* retmy_strstr(arr, src);printf(%s\n, ret);return 0;
}strtok函数
功能用于处理带标记的字符串。头文件为#includestring.h。 注意
1.参数2strDelimit指向的字符串定义了用作分隔符的集合,注意参数2必须是字符串而’\0‘代表的是字符串结束符通常用于标记字符串的末尾并不作为分隔符。
2.strToken指向的字符串它包含了0个或者多个strDelimit指向字符串的分隔符标记。
3.strtok函数找到strDelimit指向字符串中的下一个分隔符的标记并会自动保存这个标记符在字符串的位置返回一个指向这个标记的指针。
4.当第一个参数不为NULL找到第一个分割符标记该函数内部会自动保存这个标记符在字符串的位置进行第二次使用strtok函数时函数的第一个参数为NULL,该函数会从上次strtok函数保存的上个分割标记符后一个位置处查询下一个分割标记符并保存下一个分割标记符所在字符串中的位置直到不存在分隔符停止查找。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{char arr1[] naifu,naiyou.fsq#zzx;const char* arr2 ,.#;for (char* ret strtok(arr1, arr2); ret ! NULL; retstrtok(NULL, arr2)){printf(%s\n, ret);}return 0;
}错误信息报告
strerror函数
功能返回错误码所对应的错误信息。头文件为#includestring.h。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h //strerror库函数的头文件
#includeerrno.h //必须包含的头文件
int main()
{FILE* p fopen(lala.txt, r);if (p NULL){printf(%s\n, strerror(errno)); //errno存放错误码return 1;}fclose(p);p NULL;return 0;
}strerror函数可以用于确定库函数在执行时发生的错误的原因。当库函数遇到错误时它会设置一个全局变量errnoC语言会将错误码存放在errno这个全局变量中strerror函数使用errno确定特定错误码对应的错误消息。
perror函数
功能返回错误码所对应的错误信息。头文件为#includestdio.h。 与strerror作用效果相同只是perror会输出string指向的字符串内容在加个冒号在输出错误码所对应的错误信息在文件操作中确定错误信息是什么常用perror函数。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
int main()
{FILE* p fopen(lala.txt, r);if (p NULL){perror(fopen);return 1;}fclose(p);p NULL;return 0; 字符分类函数 头文件为#includectype.h。
大小写转化函数
头文件为#includectype.h
内存操作函数
memcpy函数
功能从src位置向后拷贝count个字节的内容到dest指向的字符串中遇到\0不会停下来。若拷贝的字节数大于源头字符串的总字节数超过的字节数拷贝的内容为随机值。 头文件为#includestring.h。
注意memecpy适用于不重叠数据或者无关联的数据拷贝。 #define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{int count 4;int arr[10] { 1,2,3,4,5,6 };int src[6] { 7,8,9,10,11,12 };memcpy(arr, src, sizeof(arr[0])*count);for (int i 0; i 10; i)printf(%d , arr[i]);return 0;
}#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includestring.h
int main()
{int count 3;int arr[10] { 1,2,3,4,5,6 };int src[3] { 7,8,9};memcpy(arr, src, sizeof(arr[0])*count);for (int i 0; i 10; i)printf(%d , arr[i]);return 0;
}memcpy函数模拟实现
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
#includestring.h
void* my_memcpy(void* dest, void* src, int count) //适用于任意类型
{assert(dest src);while (count--){*(char*)dest *(char*)src; //对空指针进行解引用操作具有临时性有效时长仅在其所在的语句中(char*)dest (char*)dest 1; //char*)dest因优先级(),destNULL)先与结合不能对空指针进行加减、解引用操作(char*)src (char*)src 1;}return ;
}int main()
{int count 4;int arr[10] { 1,2,3,4,5,6,7,8 };int src[6] { 9,10,11,12 };int len sizeof(arr) / sizeof(arr[0]);my_memcpy(arr, src, sizeof(arr[0] )* count);for (int i 0; i len; i){printf(%d , arr[i]);}return 0;
}问题memcpy可以拷贝重叠数据吗 答memcpy不可以拷贝重叠数据会造成数据被覆盖。
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
#includestring.h
void* my_memcpy(void* dest, void* src, int count) //适用于任意类型
{assert(dest src);while (count--){*(char*)dest *(char*)src; //对空指针进行解引用操作具有临时性有效时长仅在其所在的语句中(char*)dest (char*)dest 1; //char*)dest因优先级(),destNULL)先与结合不能对空指针进行加减、解引用操作(char*)src (char*)src 1;}return ;
}int main()
{int count 5;int arr[10] { 1,2,3,4,5,6,7,8 };int src[6] { 9,10,11,12 };int len sizeof(arr) / sizeof(arr[0]);my_memcpy(arr2, arr, sizeof(arr[0] )* count); //memcpy拷贝重叠数据for (int i 0; i len; i){printf(%d , arr[i]);}return 0;
}memmove函数
功能从src位置向后拷贝count个字节的内容到dest指向的字符串中遇到\0不会停下来。若拷贝的字节数大于源头字符串的总字节数超过的字节数拷贝的内容为随机值。 头文件为#includestring.h。
注意memmove既适用于重叠数据或者有关联的数据拷贝又适用于不重叠数据或者无关联的数据拷贝。 重叠数据或者有关联的数据拷贝
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
int main()
{int count 5;int arr[10] { 1,2,3,4,5,6,7,8 };int len sizeof(arr) / sizeof(arr[0]);memmove(arr2, arr, sizeof(arr[0] )* count);for (int i 0; i len; i){printf(%d , arr[i]);}return 0;
}不重叠数据或者无关联的数据拷贝
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
int main()
{int count 5;int arr[10] { 1,2,3,4,5,6,7,8 };int src[5] { 9,10,11,12,13 };int len sizeof(arr) / sizeof(arr[0]);memmove(arr,src, sizeof(arr[0] )* count);for (int i 0; i len; i){printf(%d , arr[i]);}return 0;
}memmove函数模拟实现
memmove模拟实现图
#define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
#includeassert.h
void* my_memmove(void* dest, const void* src, int count)
{void* ret dest;if (dest src) //从前往后拷贝{while (count--){*((char*)dest) *((char*)src);dest (char*)dest 1;src (char*)src 1;}}else //从后往前拷贝{while (count--){*((char*)dest count) *((char*)src count);}}return ret;
}int main()
{int count 5;int arr[10] { 1,2,3,4,5,6,7,8,9,10 };my_memmove(arr2, arr, sizeof(int) * count); //重叠数据for (int i 0; i 10; i){printf(%d , arr[i]);}return 0;
}问题memmove与memcp有何区别
答memmove既可以处理重叠数据又可处理不重叠数据100%。 memcpy被规定来只能用来处理不重叠或者无关联的数据60%但在有些编译器上memcpy也可用来处理重叠数据所以一般处理重叠数据的拷贝选择memmove,处理不重叠的数据选择memcpy。
memset函数
功能将dest指向的内存空间的前count字节的内容全部设置为c。 头文件为#includestring.h。 #define _CRT_SECURE_NO_WARNINGS 1
#include stdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };int count 5;memset(arr, 0, sizeof(int) * count);for (int i 0; i 10; i)printf(%d , arr[i]);return 0;
}应用场景常适用于初始化一块连续的内存空间eg静态版通讯录实现。
memcmp函数
功能将dest指向的内存空间前count字节的内容与src指向的内存空间前count字节的内容相比较比较到在count字节范围内有一个空间结束、两空间中有一个字节不相等前num个字节全部比完就停止比较了返回值与strncmp相同。
铁铁们字符函数和字符串函数知识总结就到此结束啦若博主有不好的地方请指正欢迎铁铁们留言请动动你们的手给作者点个鼓励吧你们的鼓励就是我的动力✨