今天这篇博客将会跟大家介绍三个字符串函数,分别是strstr、strtok和strerror。首先,我们来学习一下strstr函数。
1.strstr
char * strstr ( const char *str1, const char * str2);
strstr函数是查找子字符串的函数,返回指向str1中第一次出现的str2的指针,如果str2不是str1的子字符串,则返回空指针。然后str2为空字符串,就直接返回str1。
代码示例
如何使用strstr函数并不是我们的重点,重点是学会去模拟实现strstr函数。接下来就是strstr函数的模拟实现。
模拟实现strstr函数
#include <stdio.h> #include <string.h> #include <assert.h> char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); const char* s1 = NULL; const char* s2 = NULL; const char* mark = str1; if (*str2 == '\0') { //如果str2为空字符串,就直接返回str1 return (char*)str1; } while (*mark) { // *mark !='\0'进入循环 s1 = mark; s2 = str2; while (*s1 && *s2 && (*s1 == *s2)) { //该循环条件避免当两个字符串完全相等时出现bug //比如"abc"和"abc" //如果循环条件不加上*s1 && *s2的话,当*s1和*s2都等于'\0'时,符合循环条件 //s1++ s2++ 会越界访问 造成bug s1++; s2++; } if (*s2 == '\0') { return (char*)mark; } mark++; } return NULL; } int main() { char arr1[] = "abbbcdef"; char arr2[] = "bbc"; //在arr1中查找是否包含arr2数组 //如果包含,则返回第一次出现arr2数组的地址 //如果不包含,则返回空指针 char* ret = my_strstr(arr1, arr2); if (ret == NULL) { printf("没找到\n"); } else printf("找到了\n"); return 0; }
2.strtok
char * strtok ( char * str, const char * sep );
strtok函数是字符串分割函数,对于strtok函数,我们需要注意一下几点:
sep参数是个字符串,定义了用作分隔符的字符集合。
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标记,直至到字符串的'\0'为止。
如果字符串中不存在更多的标记,则返回 NULL 指针。
strtok函数的第一个参数必须为字符数组,不能是常量字符串。
代码示例
#include <stdio.h> #include <string.h> int main() { char arr[] = "zzjoy@sztu.cn"; //-->"zzjoy\0" "sztu\0" "cn\0" char* p = "@.";//分隔符集合 char temp[20] = { 0 }; strcpy(temp, arr); //zzjoy@sztu.cn //zzjoy\0sztu.cn //zzjoy\0sztu\0cn char* ret = NULL; ret = strtok(temp, p);//第一次调用strtok函数的第一个参数是temp,以后都是NULL 返回第一个字符的地址 printf("%s\n", ret); ret = strtok(NULL, p); printf("%s\n", ret); ret = strtok(NULL, p); printf("%s\n", ret); return 0; }
上面代码中的p是指向"@.",调用strtok函数遇到arr中的@和.,会将它们转化成'\0',记下该'\0'的位置并返回字符串第一个字符的地址。同时我们还要知道的是,第一次调用strtok函数时的第一个参数是字符数组,以后调用strtok函数第一个参数都是NULL,以找到上一次的标记。
对于上面的代码,我们是知道arr中有几个分隔符,也可以知道调用几次strtok函数。但是很多时候,我们是不知道的,因此我们可以对上面的代码进行优化。
代码优化
#include <stdio.h> #include <string.h> int main() { char arr[] = "zzjoy@sztu.cn"; //-->"zzjoy\0" "sztu\0" "cn\0" char* p = "@.";//分隔符集合 char temp[20] = { 0 }; strcpy(temp, arr); char* ret = NULL;//优化 for (ret = strtok(temp, p); ret != NULL;ret=strtok(NULL,p)) { //注意strtok函数没找到分隔符就返回NULL printf("%s\n", ret); } return 0; }
3.strerror
char * strerror ( int errnum );
strerror函数是将错误码转化为与其对应的错误信息。我们在调用C语言中的库函数有可能会遇到调用失败的情况,而调用失败就会有错误码。
通过上面的代码,我们可以看到strerror函数将错误码转化成相应的错误信息。不过,strerror函数是很少这样来用的。接下来,我们来看下面的代码,以阅读的形式打开test.txt文件。
我们可以看到,输出的介绍结果是 No such file or directory,就是在test_7_14文件夹中没有test.txt的文件。那我们在该路径下,新建一个test.txt的文件,再运行这个代码,会输出什么结果呢?在新建文件的时候,注意查看自己的文件后缀名是否有显示。
除了 strerror 函数,还有另一个 perror 函数也有类似的功能。 perror 函数能够将你输入的一些信息和现在的errno所对应的错误一起输出。
现在代码并没有输出 No such file or directory,说明我们的这个代码是成功打开test.txt文件了的。以上就是本篇博客的全部内容了,如果大家觉得有收获的话,可以点个赞支持一下!!!