1.字符串查找基础
1.1查找一个字符
函数原型: char *strchr( char const *str , int ch);
函数原型: char *strrchr( char const *str , int ch);
第一个参数是被查罩数组指针而第二个参数是int型,但是他包含了一个字符值。函数1为返回第一次出现ch的位置指针而第二个函数是返回最后一次出现ch的位置即最右侧地址。查找失败均返回NULL指针。
例子:
char srting[20] = "Hello there, honey.";
char *ans;
ans = strchr( string , 'h')
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strchr(const char *s,int c);
- *用法:#include <string.h>
- *功能:查找字符串s中首次出现字符c的位置
- *说明:返回首次出现c的位置的指针,如果s中不存在c则返回NULL。
- *使用C函数库中的strchr
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char s[] = "This sample string";
- char *p = strchr(s,'p');
- if(p != NULL)
- {
- printf("find the char in : %d\n",p - s + 1);
- }
- else printf("could not find the char\n");
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strchr(const char *s,int c);
- *用法:#include <string.h>
- *功能:查找字符串s中首次出现字符c的位置
- *说明:返回首次出现c的位置的指针,如果s中不存在c则返回NULL。
- *自己实现strchr
- */
- #include <cstdio>
- char * _strchr(const char * s,int ch)
- {
- while(*s && (*s != (char)ch))
- {
- s++;
- }
- if(*s == (char)ch) return (char *)s;
- return NULL;
- }
- int main(int args,char ** argv)
- {
- char s[] = "This sample string";
- char *p = _strchr(s,'p');
- if(p != NULL)
- {
- printf("find the char in : %d\n",p - s + 1);
- }
- else printf("could not find the char\n");
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:extern char *strrchr(char *s,char c);
- *用法:#include <string.h>
- *功能:查找字符串s中最后一次出现字符c的位置
- *说明:返回最后一次出现c的位置的指针,如果s中不存在c则返回NULL。
- *使用C函数库中的strrchr
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char str[] = "This is a sample string";
- char *pch;
- pch = strrchr(str,'s');
- printf("The last occurence of 's' found at : %d",pch - str + 1);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strrchr(const char *s,int ch);
- *用法:#include <string.h>
- *功能:查找字符串s中最后一次出现字符c的位置
- *说明:返回最后一次出现c的位置的指针,如果s中不存在c则返回NULL。
- *自己实现strrchr
- */
- #include <cstdio>
- char * _strrchr(const char * str,int ch)
- {
- char * start = (char *)str;
- while(*str++)/*get the end of the string*/
- ;
- while(--str != start && *str != (char)ch)
- ;
- if(*str == (char)ch)
- return((char *)str);
- return NULL;
- }
- int main(int args,char ** argv)
- {
- char str[] = "This is a sample string";
- char *pch;
- pch = _strrchr(str,'s');
- printf("The last occurence of 's' found at : %d",pch - str + 1);
- getchar();
- return 0;
- }
1.2查找仁和几个字符
函数原型: char *strpbrk( char const *str , char const *group);
函数功能是查找仁和一组字符第一次在字符串中出现的位置,返回值为指向第一个匹配group中仁和一个字符的字符位置,未匹配则返回一个NULL指针。
例子:
char string[20] = "Hello there. honey.";
char *ans;
ans = strpbrk ( string , "aeiou");
ans所指向的位置为string+1,因为这个位置是第二个参数中的字符第一次出现的位置。查找一个字符一样这个函数也是区分大小写的。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strpbrk(const char *s1, const char *s2);
- *用法:#include <string.h>
- *功能:在字符串s1中寻找字符串s2中任何一个字符相匹配的第一个字符的位置,
- * 空字符NULL不包括在内。
- *说明:返回指向s1中第一个相匹配的字符的指针,如果没有匹配字符则返回空指针NULL。
- *使用C函数库中的strpbrk
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char str[] = "This is a sample string";
- char keys[] = "aeiou";
- printf("Vowels in '%s' : ",str);
- char * pch;
- pch = strpbrk(str,keys);
- while(pch != NULL)
- {
- printf("%c ",*pch);
- pch = strpbrk(pch + 1,keys);
- }
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strpbrk(const char *s1, const char *s2);
- *用法:#include <string.h>
- *功能:在字符串s1中寻找字符串s2中任何一个字符相匹配的第一个字符的位置,
- * 空字符NULL不包括在内。
- *说明:返回指向s1中第一个相匹配的字符的指针,如果没有匹配字符则返回空指针NULL。
- *自己实现strpbrk
- */
- #include <cstdio>
- #include <cstring>
- char * _strpbrk(const char * string,const char * control)
- {
- const unsigned char *str = (const unsigned char *)string;
- const unsigned char *ctrl = (const unsigned char *)control;
- unsigned char map[32];
- int count;
- /*clear the map*/
- memset(map,0,32*sizeof(unsigned char));
- /*set bit in the control map*/
- while(*ctrl)
- {
- map[*ctrl >> 3] |= (0x01 << (*ctrl & 7));
- ctrl++;
- }
- /*search control in str*/
- while(*str)
- {
- if((map[*str >> 3] & (1 << (*str & 7))))
- return((char *)str);
- str++;
- }
- return NULL;
- }
- int main(int args,char ** argv)
- {
- char str[] = "This is a sample string";
- char keys[] = "aeiou";
- printf("Vowels in '%s' : ",str);
- char * pch;
- pch = _strpbrk(str,keys);
- while(pch != NULL)
- {
- printf("%c ",*pch);
- pch = _strpbrk(pch + 1,keys);
- }
- getchar();
- return 0;
- }
1.3查找一个子串
函数原型:char *strstr( char const *s1, char const *s2);
函数原型:char *strrstr ( char const *s1 , char const *s2);
函数功能在s1中查找整个s2第一次出现的起始位置,并返回一个指向该位置的指针如果s2并没有完整地出现在s1的任何地方,则返回NULL指针如果第二个函数为空则返回s1。,第二个是搜索s2最有出现位置,并返回一个指向该位置的指针。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strstr(const char *haystack, const char *needle);
- *用法:#include <string.h>
- *功能:从字符串haystack中寻找needle第一次出现的位置(不比较结束符NULL)。
- *说明:返回指向第一次出现needle位置的指针,如果没找到则返回NULL。
- *使用C函数库中的strstr
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char str[] = "This is a simple string";
- char * pch = _strstr(str,"simple");
- strncpy(pch,"sample",6);
- printf("%s\n",str);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:char *strstr(const char *haystack, const char *needle);
- *用法:#include <string.h>
- *功能:从字符串haystack中寻找needle第一次出现的位置(不比较结束符NULL)。
- *说明:返回指向第一次出现needle位置的指针,如果没找到则返回NULL。
- *自己实现strstr
- */
- #include <cstdio>
- #include <cstring>
- char * _strstr(const char * str1,const char * str2)
- {
- char * cp = (char *)str1;
- char * s1;
- char * s2;
- if(!*str2)
- return ((char *)str1);
- while(*cp)
- {
- s1 = cp;
- s2 = (char *)str2;
- while(*s1 && *s2 && !(*s2 - *s1))
- {
- s1++;
- s2++;
- }
- if(!*s2)
- return (cp);
- cp++;
- }
- return NULL;
- }
- int main(int args,char ** argv)
- {
- char str[] = "This is a simple string";
- char * pch = _strstr(str,"simple");
- strncpy(pch,"sample",6);
- printf("%s\n",str);
- getchar();
- return 0;
- }
#include <string.h> //在字符串s1中查找字符串s2最后出现的位置,并返回一个指向该位置的指针。
char *strrstr ( cahr const *s1, char const *s2)
{
register char *last;
register char *current; //把指针初始化为找到的第一个位置
last = NULL; //旨在第二个字符串不为空的时候才找,如果为空,返回NULL
if ( *s2 != '\0') //查找s2在s1中出现的位置
{
chrrent = strstr (s1,s2); //每次找到是,让指针指向它的起始位置。然后查找下一个匹配位置。
while ( current != NULL)
{
last = current ;
current = strstr ( last +1, s2);
}
}
return last ; //返回指向我们找到的最后一次匹配的起始位置指针。
}
2.高级字符串查找
2.1查找一个字符串前缀
函数原型:size_t strspn ( char const * str, char const *group);
函数说明:strspn()从参数str字符串的开头计算连续的字符,而这些字符都完全是group 所指字符串中的字符。简单的说,若strspn()返回的数值为n,则代表字符串str 开头连续有n 个字符都是属于字符串group内的字符,返回字符串str开头连续包含字符串group内的字符数目。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:size_t strspn(const char * str1,const char * str2);
- *用法:#include <string.h>
- *功能:若strspn()返回的数值为n,
- * 则代表字符串str1开头连续有n个字符都是属于字符串str2内的字符.
- *说明:返回字符串str1开头连续包含字符串str2内的字符数目.
- *使用C函数库中的strspn
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char str[] = "12999th";
- char keys[] = "1234567890";
- int i = strspn(str,keys);
- printf("the initial string has %d numbers\n",i);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:size_t strspn(const char * str1,const char * str2);
- *用法:#include <string.h>
- *功能:若strspn()返回的数值为n,
- * 则代表字符串str1开头连续有n个字符都是属于字符串str2内的字符.
- *说明:返回字符串str1开头连续包含字符串str2内的字符数目.
- *自己实现strspn
- */
- #include <cstdio>
- #include <cstring>
- size_t _strspn(const char * string,const char * control)
- {
- const char * str = (const char *)string;
- const char * ctrl = (const char *)control;
- unsigned char map[32];
- int count = 0;
- /*clear the map*/
- memset(map,0,32*sizeof(unsigned char));
- //memset(map,0,32);
- /*set bits in control map*/
- while(*ctrl)
- {
- map[*ctrl >> 3] |= (0x01 << (*ctrl & 7));
- ctrl++;
- }
- /*count the str's char num in control*/
- if(*str)
- {
- count = 0;
- while((map[*str >> 3] & (0x01 << (*str & 7))))
- {
- count++;
- str++;
- }
- return count;
- }
- return 0;
- }
- int main(int args,char ** argv)
- {
- char str[] = "129th";
- char keys[] = "1234567890";
- int i = _strspn(str,keys);
- printf("the initial string has %d numbers\n",i);
- getchar();
- return 0;
- }
函数原型:size_t strcspn ( char const * str, char const *group);
函数说明:strcspn()从参数str 字符串的开头计算连续的字符, 而这些字符都完全不在参数group所指的字符串中. 简单地说, 若strcspn()返回的数值为n, 则代表字符串str 开头连续有n 个字符都不含字符串group内的字符。
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:size_t strcspn(const char *s1,const char *s2);
- *用法:#include <string.h>
- *功能:在字符串s1中搜寻s2中所出现的字符。
- *说明:返回第一个出现的字符在s1中的下标值,
- * 亦即在s1中出现而s2中没有出现的子串的长度。
- *使用C函数库中的strcspn
- */
- #include <cstdio>
- #include <cstring>
- int main(int args,char ** argv)
- {
- char str[] = "fcb373";
- char keys[] = "1234567890";
- int i = strcspn(str,keys);
- printf("The first number in str is in position : %d",i +1);
- getchar();
- return 0;
- }
- /*
- *copyright@nciaebupt 转载请注明出处
- *原型:size_t strcspn(const char *s1,const char *s2);
- *用法:#include <string.h>
- *功能:在字符串s1中搜寻s2中所出现的字符。
- *说明:返回第一个出现的字符在s1中的下标值,
- * 亦即在s1中出现而s2中没有出现的子串的长度。
- *自己实现strcspn
- */
- #include <cstdio>
- size_t _strcspn(const char * string,const char * control)
- {
- const unsigned char * str = (const unsigned char *)string;
- const unsigned char * ctrl = (const unsigned char *)control;
- unsigned char map[32];
- int count = 0;
- //clear the bit map
- for(count = 0;count < 32;count++)
- {
- map[count] = 0;
- }
- //set bit in control map
- while(*ctrl)
- {
- map[*ctrl >> 3] |= (0x01 << (*ctrl & 7));
- ctrl++;
- }
- count = 0;
- map[0] |= 1;/*null chars not considered*/
- while(!(map[*str >> 3] & (0x01 << (*str & 7))))
- {
- count++;
- str++;
- }
- return count;
- }
- int main(int args,char ** argv)
- {
- char str[] = "fcb373";
- char keys[] = "1234567890";
- int i = _strcspn(str,keys);
- printf("The first number in str is in position : %d",i +1);
- getchar();
- return 0;
- }
2.2查找标记
函数原型:char *strtok ( char *str , char const *sep);
函数功能:函数说明:strtok()用来将字符串分割成一个个片段。参数s 指向欲分割的字符串,参数delim 则为分割字符串,当strtok()在参数s 的字符串中发现到参数delim 的分割字符时则会将该字符改为\0 字符。在第一次调用时,strtok()必需给予参数s 字符串,往后的调用则将参数s 设置成NULL。每次调用成功则返回下一个分割后的字符串指针。
返回值:返回下一个分割后的字符串指针,如果已无从分割则返回NULL。
范例
- #include <string.h>
- main(){
- char s[] = "ab-cd : ef;gh :i-jkl;mnop;qrs-tu: vwx-y;z";
- char *delim = "-: ";
- char *p;
- printf("%s ", strtok(s, delim));
- while((p = strtok(NULL, delim)))
- printf("%s ", p);
- printf("\n");
- }
执行结果:
ab cd ef;gh i jkl;mnop;qrs tu vwx y;z //-与:字符已经被\0 字符取代
- //strtok源码剖析 位操作与空间压缩
- //http://blog.youkuaiyun.com/morewindows/article/details/8740315
- //By MoreWindows( http://blog.youkuaiyun.com/MoreWindows )
- #include <stdio.h>
- // strtok源码剖析
- char* __cdecl MyStrtok(char * string, const char * control)
- {
- unsigned char *str;
- const unsigned char *ctrl = (const unsigned char *)control;
- static unsigned char* _TOKEN = NULL;
- //注意这里使用了static类型,实际的strtok函数出于线程安全会使用TLS
- //由于char类型占一个字节取值范围为0~255
- //所以可以打个bool flag[255]这样的哈希表
- //来记录哪些字符为delimiter characters
- //然后根据《位操作基础篇之位操作全面总结》中的位操作与空间压缩
- //http://blog.youkuaiyun.com/morewindows/article/details/7354571#t6
- //可以将数组大小取255/8即32
- unsigned char map[32];
- int count;
- // Clear control map
- for (count = 0; count < 32; count++)
- map[count] = 0;
- // Set bits in delimiter table
- do {
- //map[*ctrl >> 3] |= (1 << (*ctrl & 7));//strtok原来的代码
- map[*ctrl / 8] |= (1 << (*ctrl % 8));
- } while (*ctrl++);
- // Initialize str
- // If string is NULL, set str to the saved pointer
- //(i.e., continue breaking tokens out of the string from the last strtok call)
- if (string != NULL)
- str = (unsigned char *)string;
- else
- str = (unsigned char *)_TOKEN;
- // Find beginning of token (skip over leading delimiters). Note that
- // there is no token iff this loop sets str to point to the terminal
- // null (*str == '\0')
- //while ( (map[*str >> 3] & (1 << (*str & 7))) && *str )//strtok原来的代码
- while ( (map[*str / 8] & (1 << (*str % 8))) && *str )
- str++;
- string = (char *)str;
- // Find the end of the token. If it is not the end of the string,
- // put a null there.
- for ( ; *str ; str++ )
- {
- //if ( map[*str >> 3] & (1 << (*str & 7)) ) //strtok原来的代码
- if ( map[*str / 8] & (1 << (*str % 8)) )
- {
- *str++ = '\0';
- break;
- }
- }
- // Update nextoken (or the corresponding field in the per-thread data structure
- _TOKEN = str;
- // Determine if a token has been found.
- if ( string == (char *)str )
- return NULL;
- else
- return string;
- }
- int main()
- {
- printf(" strtok源码剖析 位操作与空间压缩\n");
- printf(" - http://blog.youkuaiyun.com/morewindows/article/details/8740315 -\n");
- printf(" - By MoreWindows( http://blog.youkuaiyun.com/MoreWindows ) - \n\n");
- //char szText[] = "MoreWindows (By http://blog.youkuaiyun.com/MoreWindows)";
- //char szFind[] = " ";
- char szText[] = "ab,c...d(e)f(g)hj";
- char szFind[] = ",.()";
- printf("原字符串为: %s\n", szText);
- printf("分隔后为: \n");
- char *pToken = MyStrtok(szText, szFind);
- while (pToken != NULL)
- {
- printf("%s\n", pToken);
- pToken = MyStrtok(NULL, szFind);
- }
- return 0;
- }