C语言进阶之字符串查找库函数详解
工业废气 人气:0strstr
查找strstr的文档,可知它的原型为:
char *strstr( const char *string, const char *strCharSet );
它的返回值,根据文档是这样的:
Return Value
Each of these functions returns a pointer to the first occurrence of strCharSet in string, or NULL if strCharSet does not appear in string. If strCharSet points to a string of zero length, the function returns string.
可知会返回一个指针,指向目标字符串在strCharSet中第一次出现的位置。如果没有,就返回一个空指针。
简单地说,就是查找子字符串。
由于返回值是指针,那么接收返回值就要用指针类型来接收。
#include <stdio.h> #include <string.h> int main() { char arr1[] = "abbbcdbbcef"; char arr2[] = "bbc"; char* ret = strstr(arr1, arr2); if (ret == NULL) { printf("找不到\n"); } else { printf("%s\n", ret); } return 0; }
输出结果如下:
如果我把arr2改成bbcq,那么在arr1中找不到arr2,就会返回空指针:
现在来模拟实现strstr。
分为两种情况。
情况1:
这种情况较为简单,arr1首先指向a,arr2指向b,a和b不相等,那么arr1指向下一个字符,此时arr2仍指向b,此时arr1和arr2指向的字符相等,那么arr2指向下一个字符,arr1也指向下一个字符,发现arr1和arr2指向的字符相等,那么arr2指向下一个字符,这时指向了\0,就停止了查找。
情况2:
arr1最开始指向a,arr2最开始指向b。
arr1和arr2所指向的字符不相等,那么arr1就指向下一个字符,arr2仍指向第一个b,此时arr1和arr2指向的字符相等,那么arr2指向下一个字符,arr1也指向下一个字符,发现arr1和arr2指向的字符相等,那么arr1和arr2继续指向下一个字符,此时arr1和arr2分别所指向的字符不相等,而此时arr2也不能向前指了,那么就停止了查找。
显而易见,这是有问题的!问题就在于第一个字符串里明明有第二个字符串的存在,却没有查找到。
正确的做法是,arr1指向出现的第二个b,arr2指向第一个字符,然后重新查找。
那么此时就需要有一些临时变量,不要用arr1和arr2亲自查找。
可以这样来实现模拟strstr:
#include <string.h> #include <assert.h> char* my_strstr(const char* str1, const char* str2) { assert(str1 && str2); if (*str2 == '\0')//用于判断srr2是不是空字符串 { return (char*)str1; } const char* s1 = NULL; const char* s2 = NULL; const char* cp = str1; while (*cp)//当*cp为0时终止循环 { s1 = cp; s2 = str2;//内循环每次开始前s2都指向要查找的字符串首元素,s1指向被查找的字符串里下一个字符 while (*s1 !='\0' && *s2!='\0' && *s1 == *s2) { s1++; s2++;//只要字符串不结束并且指向的字符相等就循环 } if (*s2 == '\0')//如果条件成立,说明找到了子字符串 { return (char*)cp; } cp++; } return NULL; }
strtok
这个函数不管是使用还是原理,都相当独特。其原型如下:
char *strtok( char *strToken, const char *strDelimit );
sep参数是个字符串,定义了用作分隔符的字符集合。
第一个参数指定一个字符串,它包含了0个或者多个由sep字符串中一个或者多个分隔符分割的标
记。
strtok函数找到str中的下一个标记,并将其用 \0 结尾,返回一个指向这个标记的指针。(注:strtok函数会改变被其操作的字符串,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可修改。)
strtok函数的第一个参数不为 NULL ,函数将找到str中第一个标记,strtok函数将保存它在字符串
中的位置。
strtok函数的第一个参数为 NULL ,函数将在同一个字符串中被保存的位置开始,查找下一个标
记。
如果字符串中不存在更多的标记,则返回 NULL 指针。
字符串superverybest@outlooks.net是由@和.切开的,@和.其实就是分隔符。那么要将superverybest、outlooks、net分隔开,可以这样:
#include <stdio.h> #include <string.h> int main() { char arr[] = "superverybest@outlooks.net"; char* p = "@."; char buf[50] = { 0 }; strcpy(buf, arr); char* ret = NULL; for (ret = strtok(buf, p); ret != NULL; ret=strtok(NULL, p)) { printf("%s\n", ret); } return 0; }
输出结果为:
总结
加载全部内容