我有两个字符串。让我们说'
str1="One Two Three";
和
str2="two";
我想知道是否有任何函数检查第一个字符串中第二个字符串的匹配,并返回指向第一个匹配项的指针,类似strstr()
,但不是&#39 ; t将相同的字母(大写或小写)视为两个不同的字符。
对于我的示例,该函数应在第一个字符串中找到str2
的匹配项,尽管大写"T"
为"Two"
。
答案 0 :(得分:31)
来自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
。
答案 1 :(得分:9)
虽然某些编译器的C库包含具有不区分大小写的标准字符串函数版本的扩展,例如GNU的strcasestr()
,但即使包含这些函数,这些函数的命名也不标准化。 / p>
克服缺乏标准实现的一种方法当然是实现自己的:
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;
}
答案 2 :(得分:8)
如果您使用的是Windows,则可以使用StrStrI。它的工作原理与GNU strcasestr
或其他答案中的其他手动实现的stristr
代码相同。
E.g:
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";
答案 3 :(得分:5)
接受回答后
受到@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()
的角落案例与"x",""
,"","x"
,"",""
答案 4 :(得分:2)
这是一个稍微高效的版本,在tolower()
字符串中每个字符不会调用haystack
两次:
#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;
}
答案 5 :(得分:1)
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;
}
答案 6 :(得分:0)
在不编写任何函数的情况下解决此问题的最佳方法可能是首先使用“tolower”/“toupper”将字符串转换为小写/大写,然后使用“strstr”:)
答案 7 :(得分:0)
尝试以下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;
}