strstr()函数,忽略大写或小写

我有两个字符串。 让我们说str1="One Two Three"str2="two" 。 我想知道是否有任何函数检查第一个字符串中第二个字符串的匹配,并返回指向第一个匹配项的指针,如strstr ,但不处理相同的字母,上部或小写,作为两个不同的字符。 对于我的例子,函数应该在第一个字符串中找到str2的匹配,尽管大写"T""Two" 。 我希望我已经说清楚了。 提前致谢。 🙂

strstr的联机帮助页:

 STRSTR(3) Linux Programmer's 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. 

所以你要找的是strcasestr

虽然某些编译器的C库包含具有不区分大小写的标准字符串函数版本的扩展,例如GNU的strcasestr() ,但即使包含这些函数,这些函数的命名也不标准化。

克服缺乏标准实现的一种方法当然是实现自己的:

 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 ; } 

下面的测试代码输出:

 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; } 

接受答复后

受到@Clifford和@Weather Vane的启发,我想我会尝试编写一个只使用标准库函数的解决方案。

 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; } 

strstr()strstr()情况与"x","""","x""",""等输入相匹配有点棘手

如果你在Windows上,你可以使用StrStrI 。 它的工作原理与GNU strcasestr或其他手动实现的stristr代码相同。

例如:

 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"; 

这是一个稍微高效的版本,它不会在haystack字符串中为每个字符调用tolower()两次:

 #include  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; } 

执行stristr()

 #include #include #include 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; } 

在不编写任何函数的情况下解决此问题的最佳方法可能是首先使用“tolower”/“toupper”将字符串转换为小写/大写,然后使用“strstr”:)

试试这个function

 char* stristr(const char* String, const char* Pattern) { char *pptr, *sptr, *start; for (start = (char *)String; *start; start++) { /* find start of pattern in string */ for ( ; (*start && (toupper(*start) != toupper(*Pattern))); start++) ; if (!*start) return 0; pptr = (char*)Pattern; sptr = (char*)start; while (toupper(*sptr) == toupper(*pptr)) { sptr++; pptr++; /* if end of pattern then pattern was found */ if (!*pptr) return (start); } } return 0; }