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

时间:2014-12-04 20:07:08

标签: c string

我有两个字符串。让我们说'

str1="One Two Three";

str2="two";

我想知道是否有任何函数检查第一个字符串中第二个字符串的匹配,并返回指向第一个匹配项的指针,类似strstr(),但不是&#39 ; t将相同的字母(大写或小写)视为两个不同的字符。

对于我的示例,该函数应在第一个字符串中找到str2的匹配项,尽管大写"T""Two"

8 个答案:

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