赞
踩
目录
C语言在标准库中提供了标准的字符串操作函数,可用于查找字符串中的字符、子字符串等。这给程序员提供了很大的便利,并且有利于提高程序的可移植性。本文对C语言标准库中提供的常见字符串查找相关函数进行了解读,并进行了模拟实现。
函数原型:char *strchr( const char *string, int c );
函数功能:在字符串string中查找一个字符c,并返回指向第一次出现c的位置的指针,如果字符串string中没有字符c,那么就返回空指针NULL。
函数参数:
- string:被查找的字符串
- c:想要在字符串中查找的字符,这里c采用int型是因为字符本质上是其对应的ASCII码值,字符型变量也属于整型家族。int型变量长度为4字节,char型为1字节,因此使用int型变量接受char型变量完全没有问题。
使用库函数strchr要引用头文件<string.h>
代码段2.1在字符串 arr1[ ] = "abcdeccf"中查找第一次出现字符'c'的位置,程序运行的结果:cdeccf
代码段2.1:
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[] = "abcdeccf";
- char* ret = strchr(arr1, 'c');
- printf("%s\n", ret); //cdeccf
- return 0;
- }
strchr的模拟实现代码:
- char* my_strchr(const char* str, int c)
- {
- assert(str); //指针有效性检验
- while (*str != '\0')
- {
- if (c == *str) //查找到c就返回c的位置
- {
- return str;
- }
- str++;
- }
- return NULL; //找不到c就返回NULL
- }
函数原型:char *strrchr( const char *string, int c );
函数功能:在字符串string中查找字符c最后一次出现的位置
函数参数:
- string:被查找的字符串
- c:期望在string中查找的字符
函数的返回值:若在string中查找到c,则返回c最后一次出现的位置,若没有查找到c,就返回空指针NULL。
代码段2.2实现的功能是在字符串arr1[]="abcdeccf"中查找字符c最后一次出现的位置,程序运行的结果为:cf
代码段2.2:
- int main()
- {
- char arr1[] = "abcdeccf";
- char* ret = strrchr(arr1, 'c');
- printf("%s\n", ret); //cf
- return 0;
- }
模拟实现代码:
- char* my_strrchr(const char* str, int c)
- {
- assert(str);
- char* ret = NULL; //初始化返回值为NULL
- while (*str != '\0')
- {
- if (c == *str) //在str中遇到c就将其位置暂时存入ret
- {
- ret = str;
- }
- str++;
- }
- return ret;
- }
函数原型:char *strpbrk( const char *string, const char *strCharSet );
函数功能:在字符串string中查找第一次出现strCharSet字符串中任何一个字符的位置。
函数参数:string是被查找的字符串,strCharSet为期望在string中查找的字符的集合
函数返回值:若在string中查找到了strCharSet中任意一个字符,则返回指向第一次出现这个字符的位置的指针,若找不到这样的一个字符,则返回空指针NULL。
代码段3在arr1中寻找第一次出现group字符串中任意一个元素的位置,程序运行的结果为:deccf
代码段3.1:
- int main()
- {
- char arr1[] = "abcdeccf";
- char group[] = "dhj";
- char* ret = strpbrk(arr1, group);
- printf("%s\n", ret); //deccf
- return 0;
- }
模拟实现代码:
- char* my_strpbrk(const char* str, const char* group)
- {
- assert(str && group); //指针有效性检验
- while (*str != '\0')
- {
- //调用库函数strchr,再group中查找*str,若不返回NULL,则找到了这样一个字符
- if (strchr(group, *str) != NULL)
- {
- return str;
- }
- str++;
- }
- return NULL; //找不到,返回空指针
- }
函数原型:char *strstr( const char *s1, const char *s2);
函数功能及返回值:在s1中查找整个s2第一次出现的起始位置,并返回一个指向该位置的指针,如果s2没有出现在s1的任何地方,函数将返回一个NULL指针。如果第二个参数是一个空字符串,就返回s1。
代码段4.1在字符串arr1[]="abcdecdf"中查找"cd"第一次出现的位置,程序的运行结果为:cdecdf
代码段4.1:
- int main()
- {
- char arr1[] = "abcdecdf";
- char arr2[] = "cd";
- char* ret = strstr(arr1, arr2);
- printf("%s\n", ret); //cdecdf
- return 0;
- }
模拟实现代码:
- char* my_strstr(const char* str1, const char* str2)
- {
- assert(str1); //指针有效性检验
- if (str2 == NULL) //str2是空字符串就返回str1的位置
- {
- return str1;
- }
- size_t len2 = strlen(str2); //求arr2中含有几个有效字符
- while (*str1 != '\0')
- {
- //比较str1和str2的前len2个字符是否相同
- //如果相同,返回此时str1的位置
- if (strncmp(str1, str2, len2) == 0)
- {
- return str1;
- }
- str1++;
- }
- return NULL;
- }
函数原型:size_t strspn( const char *str, const char *group );
函数功能:group字符串指定一个或多个字符。strspn返回str起始部分匹配group中任意字符的字符数。例如,arr1[] = "1234.56@abcf",arr2[] = "12389",字符串arr1中的第1、第2、第3个字符可以在arr2中找到,arr1中第4个字符无法在arr2中找到,因此,strspn(arr1,arr2)的返回值为3。
在代码段5.1中定义了三个字符串,分别为:arr1[] = "12.34.56@abcf"、arr2[] = "123456"、arr3[] = ".123456",先后执行语句strspn(arr1,arr2)和strspn(arr1,arr3),arr1的前2个字符可以在arr2中找到匹配,arr1中前8个字符可以在arr3中找的匹配。因此,程序中ret1=2,ret2=8。
代码段5.1:
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[] = "12.34.56@abcf";
- char arr2[] = "123456";
- char arr3[] = ".123456";
- size_t ret1 = strspn(arr1, arr2);
- printf("%u\n", ret1); //2
- size_t ret2 = strspn(arr1, arr3); //8
- printf("%u\n", ret2);
- return 0;
- }
模拟实现代码:
- size_t my_strspn(const char* str, const char* group)
- {
- assert(str && group); //指针有效性检验
- size_t count = 0; //str其实位置与group中任意字符匹配的字符数
- while (strchr(group, *str) != NULL)
- {
- //在group中查找*str,若不返回NULL,则表示*str这个字符可以与group中其中之一匹配
- //匹配成功就进行count++操作
- count++;
- str++;
- }
- return count;
- }
函数原型:size_t strcspn( const char *str, const char *group );
函数功能:strcspn函数的功能与strspn正好相反,它计算字符串str起始部分有几个字符无法与group中任意一个字符匹配。比如,arr1[]="123.456.78.90@abcd",arr2[ ]="@abc",arr1前面的123.456.78.90(共13个字符)与arr2无法匹配,因此,strcspn(arr1,arr2)返回的结果为12。
代码段5.2中定义两个字符串arr1和arr2,指向语句strcspn(arr1, arr2),arr1中的前12个字符无法与arr2中任意一个字符匹配,因此程序运行的结果为13。
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[] = "123.456.78.90@abcd";
- char arr2[] = "@abc";
- size_t ret = strcspn(arr1, arr2);
- printf("%u\n", ret); //13
- return 0;
- }
模拟实现代码:
- size_t my_strcspn(const char* str, const char* group)
- {
- assert(str && group); //指针的有效性检验
- size_t count = 0;
- while (strchr(group, *str) == NULL)
- {
- //调用库函数strchr,在group函数中查找不到*str就返回NULL,执行count++
- count++;
- str++;
- }
- return count;
- }
函数原型:char *strtok( char *strToken, const char *strDelimit );
函数功能:通过查找标识符,将一个字符串分隔开来,并将标识符丢弃,将源字符串标识符的位置替换为'\0'。
函数参数:strDelimit字符串定义了分隔符的集合,strToken包含零个或多个strDelimit字符串中定义的分隔符。函数在strToken查找strDelimit定义的分隔符,并将分隔符替换为\0。
函数的返回值:若在字符串中查找到了标记,就返回被标记的位置,若找不到标记,就返回空指针NULL。
注意:若strtok的第一个参数不是NULL,函数将找到字符串的第一个标记,同时,strtok函数将保存第一个标记在字符串中的位置。若strtok的第一个参数为NULL,则从上一次标记被保存的位置开始查找下一个标记。
注意:由于strtok函数会改变原来的字符串,因此,一般将字符串的一份临时拷贝传入到strtok函数中。
在代码段6.1中,定义了字符串arr1[]="123.456.789@abc#def" 和分隔符集合group[]=".@#",程序在arr1中查找分隔符.#@并打印被分隔的每一块,程序的运行结果为:123 456 789 abc def。
代码段6.1:
- #include<stdio.h>
- #include<string.h>
- int main()
- {
- char arr1[] = "123.456.789@abc#def";
- char arr[25] = { 0 };
- strcpy(arr, arr1); //取一份arr1的临时拷贝
- char group[] = ".#@";
- char* ret = arr;
- for (ret = strtok(arr, group); ret != NULL; ret = strtok(NULL, group))
- {
- printf("%s ", ret); //123 456 789 abc def
- }
- return 0;
- }
警告:由于strtok函数具有记忆功能,因此,在同一循环内不能用strtok函数同时处理两个字符串,不可以循环条件使用strtok函数,循环体内的语句也使用strtok函数。
模拟实现代码:
- char* my_strtok(char* str, const char* group)
- {
- static char* remember = NULL; //记忆字符串位置
- char* start = NULL; //定义并初始化开始查询的位置
- if (str == NULL)
- {
- //若第一个参数为NULL,则从上次查找的的分隔符位置开始查询下一个分隔符
- start = ++remember;
- }
- else
- {
- //若第一个参数不为NULL,则从这个参数指向的位置开始查询
- start = str;
- }
- assert(start); //此时,不再运行start为空指针,要进行指针有效性检验
- size_t leng = strlen(group) + 1; //group的字符数(包含末尾\0)
- char* pos = strpbrk(start, group); //求start后第一次出现分隔符的位置
- if (NULL != pos)
- {
- *pos = '\0';
- remember = pos; //记忆分隔符的下一个内存位置
- return start; //返回开始查找的位置
- }
- else
- {
- return NULL;
- }
- }
全文结束,感谢大家的阅读,敬请批评指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。