【问题标题】:In C - check if a char exists in a char array在 C 中 - 检查字符数组中是否存在字符
【发布时间】:2010-11-07 11:27:52
【问题描述】:

我正在尝试检查一个字符是否属于无效字符列表/数组。

来自 Python 背景,我以前只能说:

for c in string:
    if c in invalid_characters:
        #do stuff, etc

如何使用常规的 C 字符数组做到这一点?

【问题讨论】:

    标签: c arrays string char


    【解决方案1】:

    假设您的输入是标准的以空字符结尾的 C 字符串,您想使用 strchr

    #include <string.h>
    
    char* foo = "abcdefghijkl";
    if (strchr(foo, 'a') != NULL)
    {
      // do stuff
    }
    

    另一方面,如果您的数组不是以 null 结尾的(即只是原始数据),则需要使用 memchr 并提供大小:

    #include <string.h>
    
    char foo[] = { 'a', 'b', 'c', 'd', 'e' }; // note last element isn't '\0'
    if (memchr(foo, 'a', sizeof(foo)))
    {
      // do stuff
    }
    

    【讨论】:

      【解决方案2】:

      C 库中鲜为人知但非常有用(自 C89 以来为标准 - 意思是“永远”)的函数在一次调用中提供信息。实际上,有多种功能——财富的尴尬。与此相关的是:

      7.21.5.3 strcspn 函数

      概要

      #include <string.h>
      size_t strcspn(const char *s1, const char *s2);
      

      说明

      strcspn 函数计算字符串的最大初始段的长度 由 s1 指向的,它完全由不是来自于指向的字符串的字符组成 s2.

      返回

      strcspn 函数返回段的长度。

      7.21.5.4 strpbrk 函数

      概要

      #include <string.h>
      char *strpbrk(const char *s1, const char *s2);
      

      说明

      strpbrk 函数定位由 s1 指向的字符串中的第一个匹配项 s2指向的字符串中的字符。

      返回

      strpbrk 函数返回一个指向字符的指针,如果没有字符则返回一个空指针 from s2 发生在 s1 中。

      问题询问'对于字符串中的每个字符......如果它在无效字符列表中'。

      有了这些函数,你可以写:

      size_t len = strlen(test);
      size_t spn = strcspn(test, "invald");
      
      if (spn != len) { ...there's a problem... }
      

      或者:

      if (strpbrk(test, "invald") != 0) { ...there's a problem... }
      

      哪个更好取决于您还想做什么。还有相关的strspn() 函数有时很有用(白名单而不是黑名单)。

      【讨论】:

      • 有多少人建议strchrstrpbrk 显然是理想的解决方案。
      • 这实际上应该是公认的答案! C 并非完全没有电池...
      • 在您对 strpbrk any character from the string pointed to by s2 的描述中,但在您的示例中,您针对 "invalid" 进行测试。这不会查找字符串"invalid" 中任何单个字符的出现吗?
      • @IsaacBaker:我不确定你在问什么。在我看来,您的“不会这样”的问题是询问该功能是否会像记录的那样运行(答案是肯定的),但我敢肯定您一定有问的理由,所以我一定误解了您是什么问。
      • @JonathanLeffler:我想问/说的是:您的回答似乎有些矛盾或令人困惑。在您对strpbrk 的描述中,您有正确的定义,但是,在您的示例if (strpbrk(test, "invalid") != 0) { ...there's a problem... } 中,您似乎在寻找一个连续的字符串"invalid",但会搜索第一次出现的 "invalid" 中包含的任何 字符。这是真的和正确的吗?
      【解决方案3】:

      我相信原来的问题说:

      一个字符属于一个列表/数组 无效字符

      而不是:

      属于以空字符结尾的字符串

      如果确实如此,那么strchr 确实是最合适的答案。但是,如果字符数组没有空终止符,或者字符位于列表结构中,则您需要创建一个空终止符字符串并使用 strchr 或手动迭代集合中的元素,依次检查每个。如果集合很小,那么线性搜索就可以了。大型集合可能需要更合适的结构来缩短搜索时间 - 例如排序数组或平衡二叉树。

      选择最适合您的情况。

      【讨论】:

        【解决方案4】:

        等效的 C 代码如下所示:

        #include <stdio.h>
        #include <string.h>
        
        // This code outputs: h is in "This is my test string"
        int main(int argc, char* argv[])
        {
           const char *invalid_characters = "hz";
           char *mystring = "This is my test string";
           char *c = mystring;
           while (*c)
           {
               if (strchr(invalid_characters, *c))
               {
                  printf("%c is in \"%s\"\n", *c, mystring);
               }
        
               c++;
           }
        
           return 0;
        }
        

        请注意,invalid_characters 是一个 C 字符串,即。一个以 null 结尾的 char 数组。

        【讨论】:

        • 尽量不要挑剔,但如果它在 C 中,你不应该用等效的 printf() 调用替换 std::cout 吗?或者至少是 C 语言中存在的东西?
        • 虽然这个使用 strchr() 的循环有效,但我认为最好在用户代码中不使用循环的情况下使用 'strcspn()' 或 strpbrk()
        • @Jonathan:你说得对,但我保留了类似于 OP 的原始 Python 的代码,并回答了“检查字符数组中是否存在字符”的问题。
        • 在这种情况下循环遍历无效字符并检查它们是否存在于 mystring 中(使用 strchr),而不是检查 mystring 中的每个字符是否为无效字符不是更好吗?
        • @mk12:这取决于。假设您在大海捞针中有 N 个字符正在被搜索,而您正在寻找的针中有 M 个字符。如果大海捞针中的所有字符都有效,那么无论您采用哪种方式,最终都会得到 NxM 比较。通常,M 会比 N 小得多。如果干草堆的第一个字符是针中最后一个无效字符,则您的搜索将进行 N*(M-1) 次比较,而替代方案将只进行 M 次比较。如果大海捞针中的第一个字符是针中的第一个无效字符,则两个系统都会在 1 次比较后停止。
        【解决方案5】:

        在处理 C 字符串时使用 strchr 函数。

        const char * strchr ( const char * str, int character );
        

        这是你想要做的一个例子。

        /* strchr example */
        #include <stdio.h>
        #include <string.h>
        
        int main ()
        {
          char invalids[] = ".@<>#";
          char * pch;
          pch=strchr(invalids,'s');//is s an invalid character?
          if (pch!=NULL)
          {
            printf ("Invalid character");
          }
          else 
          {
             printf("Valid character");
          } 
          return 0;
        }
        

        在处理内存块时使用 memchr(作为非空终止数组)

        const void * memchr ( const void * ptr, int value, size_t num );
        
        /* memchr example */
        #include <stdio.h>
        #include <string.h>
        
        int main ()
        {
          char * pch;
          char invalids[] = "@<>#";
          pch = (char*) memchr (invalids, 'p', strlen(invalids));
          if (pch!=NULL)
            printf (p is an invalid character);
          else
            printf ("p valid character.\n");
          return 0;
        }
        

        http://www.cplusplus.com/reference/clibrary/cstring/memchr/

        http://www.cplusplus.com/reference/clibrary/cstring/strchr/

        【讨论】:

          【解决方案6】:

          你想要

          strchr (const char *s, int c)

          如果字符 c 在字符串 s 中,它会返回一个指向 s 中位置的指针。否则返回 NULL。因此,只需使用您的无效字符列表作为字符串。

          【讨论】:

            【解决方案7】:

            strchr 用于从开头搜索字符(strrchr 从结尾):

              char str[] = "This is a sample string";
            
              if (strchr(str, 'h') != NULL) {
                  /* h is in str */
              }
            

            【讨论】:

              猜你喜欢
              • 2017-01-27
              • 1970-01-01
              • 2021-12-27
              • 1970-01-01
              • 2022-01-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多