Strstr () function like that ignores uppercase or lowercase

I have two lines. Assume str1="One Two Three" and str2="two" . I would like to know if there is any function that checks the correspondence of the second line in the first and returns me a pointer to the first occurrence, something like strstr , but which does not handle the same letter, upper or lower case, like two different characters. For my example, the function should find a match for str2 in the first line, despite the uppercase "T" , "Two" . I hope I get it. Thanks in advance.:)

+5
source share
7 answers

From the man page for strstr :

 STRSTR(3) Linux Programmer Manual STRSTR(3) NAME strstr, strcasestr - locate a substring SYNOPSIS #include char *strstr(const char *haystack, const char *needle); #define _GNU_SOURCE #include char * strcasestr (const char *haystack, const char *needle); DESCRIPTION The strstr() function finds the first occurrence of the substring needle in the string haystack. The terminating '\0' characters are not compared. The strcasestr() function is like strstr(3), but ignores the case of both arguments. RETURN VALUE These functions return a pointer to the beginning of the substring, or NULL if the substring is not found. 

So you are looking for strcasestr .

+21
source

While some C compiler libraries have extensions with case-insensitive versions of standard string functions, such as GNU strcasestr() , naming such functions is not standardized even when turned on.

One way to overcome the lack of a standard implementation is, of course, to implement your own:

 char* stristr( const char* str1, const char* str2 ) { const char* p1 = str1 ; const char* p2 = str2 ; const char* r = *p2 == 0 ? str1 : 0 ; while( *p1 != 0 && *p2 != 0 ) { if( tolower( (unsigned char)*p1 ) == tolower( (unsigned char)*p2 ) ) { if( r == 0 ) { r = p1 ; } p2++ ; } else { p2 = str2 ; if( r != 0 ) { p1 = r + 1 ; } if( tolower( (unsigned char)*p1 ) == tolower( (unsigned char)*p2 ) ) { r = p1 ; p2++ ; } else { r = 0 ; } } p1++ ; } return *p2 == 0 ? (char*)r : 0 ; } 

Below is the test code:

 Two Three Two Three NULL cdefg CDEFG CdEfG NULL zzzz NULL zzzzz NULL 

 int main(void) { char* test = stristr( "One TTwo Three", "two" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "One Two Three", "two" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "One wot Three", "two" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "abcdefg", "cde" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "ABCDEFG", "cde" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "AbCdEfG", "cde" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "1234567", "cde" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "zzzz", "zz" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "zz", "zzzzz" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "", "" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "zzzzz", "" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr( "", "zzzz" ) ; printf( "%s\n", test == 0 ? "NULL" : test ) ; test = stristr("AAABCDX","AABC") ; printf( "%s\n", test == 0 ? "NULL" : test ) ; return 0; } 
+8
source

After accepting the answer

Inspired by @Clifford and @Weather Vane , I thought that I would try to minimize a solution that uses only standard library functions.

 char* stristr3(const char* haystack, const char* needle) { do { const char* h = haystack; const char* n = needle; while (tolower((unsigned char) *h) == tolower((unsigned char ) *n) && *n) { h++; n++; } if (*n == 0) { return (char *) haystack; } } while (*haystack++); return 0; } 

It’s a strstr() harder to match the angular cases of strstr() with inputs such as "x","" , "","x" , "",""

+3
source

If you are in windows, you can use StrStrI . It works the same way as GNU strcasestr or other manually implemented stristr code in other answers here.

eg:.

 const char needle[] = "and"; const char haystack[] = "me and you"; const char* pAnd = StrStrIA(haystack, needle); // explicitly call ascii version as windows defaults to wchar printf("%s\n", pAnd); // Prints "and you"; 
+2
source

Implementation of stristr()

 #include<stdio.h> #include<stdlib.h> #include<string.h> char *stristr (const char *str, const char *strSearch) { char *sors, *subs, *res = NULL; if ((sors = strdup (str)) != NULL) { if ((subs = strdup (strSearch)) != NULL) { res = strstr (strlwr (sors), strlwr (subs)); if (res != NULL) res = str + (res - sors); free (subs); } free (sors); } return res; } int main() { char *str1 = "One Two Three"; char *str2 = "two"; char *sptr = stristr(str1, str2); if (sptr) printf ("Substring is at index %d\n", sptr - str1); return 0; } 
+1
source

Here is a slightly more efficient version that does not call tolower() twice per character in the haystack string:

 #include <ctype.h> char *stristr4(const char *haystack, const char *needle) { int c = tolower((unsigned char)*needle); if (c == '\0') return (char *)haystack; for (; *haystack; haystack++) { if (tolower((unsigned char)*haystack) == c) { for (size_t i = 0;;) { if (needle[++i] == '\0') return (char *)haystack; if (tolower((unsigned char)haystack[i]) != tolower((unsigned char)needle[i])) break; } } } return NULL; } 
+1
source

The best way to solve this problem without writing any function is to first convert the string to lowercase or uppercase using "tolower" / "toupper" and then use "strstr" :)

0
source

Source: https://habr.com/ru/post/1208383/


All Articles