51

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

来自 Python 背景,我曾经只能说:

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

如何使用常规 C char 数组执行此操作?

4

7 回答 7

49

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 函数从 s2 指向的字符串中定位任何字符在 s1 指向的字符串中的第一次出现。

退货

strpbrk 函数返回一个指向该字符的指针,如果 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()一些有时有用的相关功能(白名单而不是黑名单)。

于 2009-07-01T23:07:09.113 回答
33

等效的 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 字符串,即。一个以空结尾的char数组。

于 2009-07-01T21:50:40.733 回答
28

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

#include <string.h>

char* foo = "abcdefghijkl";
if (strchr(foo, 'a') != NULL)
{
  // do stuff
}

另一方面,如果您的数组不是以空值结尾的(即只是原始数据),则需要使用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
}
于 2009-07-01T21:50:26.117 回答
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/

于 2009-07-01T21:49:29.440 回答
4

你要

strchr (const char *s, int c)

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

于 2009-07-01T21:52:12.307 回答
2

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

  char str[] = "This is a sample string";

  if (strchr(str, 'h') != NULL) {
      /* h is in str */
  }
于 2009-07-01T21:51:50.967 回答
1

我相信原来的问题说:

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

并不是:

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

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

选择最适合您的情况。

于 2009-07-01T22:03:00.227 回答