网站开发网页,济南制作网站的公司,电子商务网站,网站数据库特点介绍
字符串函数#xff0c;简单说#xff0c;就是处理字符串的函数#xff0c;头文件是string.h#xff0c;以下是今天的讲解中会讲到的一系列字符串函数 头文件#xff1a;#includestring.hstrlen#xff1a;求字符串长度strcpy#xff1a;拷贝字符串strcat简单说就是处理字符串的函数头文件是string.h以下是今天的讲解中会讲到的一系列字符串函数 头文件#includestring.hstrlen求字符串长度strcpy拷贝字符串strcat追加字符串strcmp比对字符串strstr一个字符串中找一个字符串strncpy拷贝字符串拷贝指定字符串个数strncmp比对字符串比较指定个数字符个数strncat追加字符串追加指定个数个字符strtok提取被分隔字符分隔字符串strerror可将参数部分错误码对应的错误信息返回 strlen 函数声明size_t strlen(const char* str); 功能求字符串长度 使用条件字符串以\0结尾 //函数自实现
#include assert.h
int my_strlen(const char* str)
{assert(str);int count 0;while (*str ! \0) {count;str;}return count;
}
在库函数实现strlen时是以\0为结尾判断标识的如果在字符串中间混入了\0那么字符串长度的计算就会提前结束计算的结果也会随之错误反之如果字符串结尾没有遇到\0那么在计时函数会一直顺着地址找下去直到找到\0为止这时候strlen返回的结果就是不可预测的了。
此处注明一下sizeof和strlen的区别首先sizeof是一个操作符不是函数其返回的值是数据类型所占内存大小可处理的不只是字符串。而strlen恰相反其只能用来处理字符串并计算其长度。
同时也要注意到strlen函数的返回值为size_t无符号整型。
下面我举一个关于size_t易错的题
//问以下代码的输出结果
#includestdio.h
#includestring.h
int main()
{if(strlen(abc) - strlen(abcd) 0)printf(大于\n);else printf(小于\n);return 0;
}
大家的第一反应是什么呢我猜应该是输出小于。但仔细想一想size_t作为无符号整型相减会产生负数吗不会的所以最后的结果是打印大于。
//函数使用样例
#includestdio.h
#inlcudestring.h
int main()
{char arr[] abcdef;int la strlen(arr);printf(%s\n, la);//打印6return 0;
}
strcpy 函数声明char* strcpy(char* destination, const char* source); 功能将参数source字符串拷贝至参数destination所指的地址 返回值字符串destination起始地址 使用条件源字符串必须以\0结尾 目标空间必须大于等于拷贝过去字符所占的空间包括\0 //自实现
#includeassert.h
char* my_strcpy(char* str1, const char* str2)
{assert(str1 str2);char* ret str1;while (*str1 *str2);*str1 *str2;return ret;
}
//使用样例
#includestdio.h
#includestring.h
int main() {char arr1[20] abcdef;char arr2[20] { 0 };char* p1 strcpy(arr2, arr1);printf(%s\n, arr2);//打印abcdefreturn 0;
}
strcat 函数声明char* strcat(char* destination,const char* source); 功能将source字符串追加到destination字符串末尾 返回值destination字符串起始地址 使用条件两字符串均以\0结尾 目标空间可被修改 destination末尾\0会被覆盖 目标空间足够大 注追加位置destination字符串\0及其后面 //自实现
char* my_strcat(char* dest, const char* src)
{char* ret dest;while (*dest) dest;while (*dest *src);return ret;
}//样例使用
#inludestdio.h
#incluestring.h
int main() {char arr1[20] abcdef;char arr2[] cd;printf(%s\n,strcat(arr1, arr2));//打印abcdefcdreturn 0;
} strcmp 函数声明int strcmp(const char* str1,const char* str2); 功能比较字符串 返回值两字符串相同返回0 前一个字符串在字典排序靠前返回负数 后一个字符串在字典排序靠前返回正数 注区分大小写比较如果不希望区分可参考stricmp //自实现
int my_strcmp(const char* s1, const char* s2)
{while (*s1 *s2) {if (*s1 \0)return 0;s1;s2;}if (*s1 *s2)return 1;else return -1;
}
//代码使用样例
#includestdio.h
#includestring.h
int main() {char arr1[] abcdef;char arr2[] cd;printf(%d\n, strcmp(arr1, arr2));//打印一个负数return 0;
}
strstr 函数声明char* strstr(const char* str1,const char* str2); 功能检索str2在str1中第一次出现的位置 返回值 返回子串str2在str1中第一次出现的位置找不到返回空指针 //自实现
char* my_strstr(const char* str1,const char* str2)
{const char* cur str1;const char* s1 NULL;const char* s2 NULL;if (!*str2)return (char*)str1;while (*cur) {s1 cur;s2 str2;while (*s1 *s2) {s1;s2;}if (*s2 \0)return (char*)cur;cur;}return NULL;
}
以上自实现代码是一份暴力查找版算法和时间复杂度并不像库函数中那样是最优的如果想了解真正的内部实现可以去了解KMP算法此代码只是想让读者更容易了解此函数的功能。
//使用样例
#includestdio.h
#includestring.h
int main() {char arr1[20] abcdef;char arr2[] cd;printf(%s\n,strstr(arr1, arr2));//打印cdefreturn 0;
}
strncpy 函数声明char* strncpy(char* destination,const char* source,size_t mun); 功能与strcpy很相似只是多累个参数拷贝指定个数的字符串 返回值字符串destination起始地址 使用条件源字符串必须以\0结尾 目标空间必须大于等于拷贝过去字符所占的空间包括\0 注在拷贝完指定个数字符后不会在串的末尾再拷贝\0 //自实现
#includeassert.h
char* my_strcpy(char* str1, const char* str2size_t num)
{assert(str1 str2);char* ret str1;while ((*str1 *str2)num!0) num--;*str1 *str2;return ret;
}
strncmp 函数声明int strcmp(const char* str1,const char* str2,size_t num); 功能和strcmp很相似但是多了个参数比较的是指定个数的字符 返回值两字符串相同返回0 前一个字符串在字典排序靠前返回负数 后一个字符串在字典排序靠前返回正数 注返回值描述的字符串比较的比较是用num个数截掉后的字符串具体可参考自实现 //自实现
#includeassert.h
int my_strncmp(const char* arr1, const char* arr2, size_t num)
{assert(arr1 arr2);for (int i 0; i num; i) {if (*(arr1 i) *(arr2 i));else if (*(arr1 i) *(arr2 i)) return 1;else return -1;}return 0;
}
//使用样例
#includestdio.h
#includestring.h
int main()
{char arr1[] abcdefg;char arr2[] abcdfea;int ret strncmp(arr1, arr2, 4);printf(%d\n, ret);//打印0ret strncmp(arr1, arr2, 5);printf(%d\n, ret);//打印一个负数return 0;
}
strncat 函数声明 char* strcat(char* destination,const char* sourcesize_t num); 功能与strcat功能相似将source指定个数的字符串追加到destination字符串末尾 返回值destination字符串起始地址 使用条件两字符串均以\0结尾 目标空间可被修改 destination末尾\0会被覆盖 目标空间足够大 注destination字符串\0及其后面 追加num个字符后会自动添加\0 //自实现
#includeassert.h
char* my_strncat(char* arr1, const char* arr2, size_t num)
{assert(arr1 arr2);char* ret arr1;while (*arr1)arr1;for (int i 0; i num; i) {*(arr1 i) *(arr2 i);}*(arr1 num) \0;return ret;
}
//使用样例
#includestdio.h
#includestring.h
#includeassert.h
int main()
{char arr1[20] abcdefg;char arr2[20] rhmotyi;char* pc strncat(arr1, arr2, strlen(arr2));printf(%s\n, pc); //打印abcdefgrhmotyipc strncat(arr1, arr2, strlen(arr2) - 2);printf(%s\n, pc); //打印abcdefgrhmotyirhmotreturn 0;
}
strtok 函数声明char* strtok(char* str, const char* sep); 功能提取被分隔字符分隔字符串 其中sep里面放的是分隔符str里面放的是带分隔符的字符串 调用一次将最首先找到的分隔符变成\0,并标记下一个位置 返回值上一次标记位置如第一次调用则返回str首元素地址 如果字符串中不存在更多标记则返回NULL 注strtok第一个参数不为NULL时函数找到str中第一个标记保存在其字符串中的位置 strtok第一个参数为NULL时函数将从被保存的位置开始寻找下一个标记 strtok内部其实存在静态变量运行结束后上一次运行数据会有存留也就是标记地址 //使用样例
#include stdio.h
#include string.h
int main()
{const char* p .;char arr[] zhangsan1623.com;char* s strtok(arr, p);printf(%s\n, s);//zhangsans strtok(NULL, p);printf(%s\n, s);//1623s strtok(NULL, p);printf(%s\n, s);//comreturn 0;
}但是上面的代码似乎有点冗杂你完全可以写在循环中见代码
//使用样例循环版
#include stdio.h
#include string.h
int main()
{const char* p .;char arr[] zhangsan1623.com;//char* s strtok(arr, p);//printf(%s\n, s);//zhangsan//s strtok(NULL, p);//printf(%s\n, s);//1623//s strtok(NULL, p);//printf(%s\n, s);//comfor (char* s strtok(arr, p); s ! NULL; s strtok(NULL, p))printf(%s\n, s);return 0;
}
这两份代码打印出来的结果是相同的
strerror 函数声明char* strerror(int errnum); 功能可以将参数部分错误码对应的错误信息字符串返回 C语言规定了一些错误码放在errno.h这个头文件中说明
//样例使用
#include stdio.h
#include string.h
int main()
{for (int i 0; i 10; i)printf(%d:%s\n,i, strerror(i));return 0;
}下面是输出结果 结语
那么本篇博客到这里就要结束了我们介绍了大部分在平时coding中可能运用到的字符串函数以及一些函数的自实现大家可以看看更利于对函数的了解。如果觉得这篇博客对你有帮助的话还请点个小赞收藏一下再走啊如果本篇博客有任何错误也欢迎在评论区讨论或者私我哦--比心♥