C语言 strstr() 函数类似,忽略大写或小写

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/27303062/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 11:36:11  来源:igfitidea点击:

strstr() function like, that ignores upper or lower case

cstring

提问by eOf

I have two strings. Lets say `

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

str1="One Two Three";

and

str2="two";

I would like to know if there is any function that checks for a match of the second string in the first one,and returns me a pointer to the first occurrence, something like strstr(), but which doesn't treat the same letter, upper or lowercase, as two different characters.

我想知道是否有任何函数可以检查第一个字符串中的第二个字符串是否匹配,并返回一个指向第一次出现的指针,例如strstr(),但不处理相同的字母,大写或小写, 作为两个不同的字符。

For my example, the function should find a match for str2in the first string, despite the uppercase "T", of "Two".

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

回答by Nathan Fellman

From the manpage for strstr:

从联机帮助页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 '
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 ;
}
' 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 what you're looking for is strcasestr.

所以你要找的是strcasestr.

回答by Clifford

While some compiler's C libraries include extensions with case insensitive versions of the standard string functions, such as GNU's strcasestr(), the naming of such functions is not standardised even when included.

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

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

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

Two Three
Two Three
NULL
cdefg
CDEFG
CdEfG
NULL
zzzz
NULL

zzzzz
NULL

The test code below outputs:

下面的测试代码输出:

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


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

回答by Orion Edwards

If you're on windows, you can use StrStrI. It works the same as the GNU strcasestror the other manually-implemented stristrcode in other answers here.

如果您使用的是 Windows,则可以使用StrStrI。它的工作原理与此处其他答案中的 GNUstrcasestr或其他手动实现的stristr代码相同。

E.g.:

例如:

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

回答by chux - Reinstate Monica

After accept answer

接受答案后

Inspired by @Cliffordand @Weather Vane, thought I'd try rolling up a solution that only used standard library functions.

受到@Clifford@Weather Vane 的启发,我想尝试汇总一个仅使用标准库函数的解决方案。

#include <ctype.h>

char *stristr4(const char *haystack, const char *needle) {
    int c = tolower((unsigned char)*needle);
    if (c == '
#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;
}
') return (char *)haystack; for (; *haystack; haystack++) { if (tolower((unsigned char)*haystack) == c) { for (size_t i = 0;;) { if (needle[++i] == '
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;
}
') return (char *)haystack; if (tolower((unsigned char)haystack[i]) != tolower((unsigned char)needle[i])) break; } } } return NULL; }

Somewhat tricky to match the corner cases of strstr()with inputs like "x","", "","x", "",""

将 的极端情况strstr()与诸如"x","", "","x", 之类的输入相匹配有点棘手"",""

回答by chqrlie

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

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

##代码##

回答by Weather Vane

Implementation of stristr()

实施 stristr()

##代码##

回答by Abhinav Gupta

The best way to solve this without writing any function may be by first converting both the string to lowercase/uppercase using "tolower"/"toupper" and then use "strstr" :)

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

回答by BattleTested

Try this function:

试试这个function

##代码##