In C - check if a char exists in a char array

2019-01-21 15:56发布

问题:

I'm trying to check if a character belongs to a list/array of invalid characters.

Coming from a Python background, I used to be able to just say :

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

How can I do this with regular C char arrays?

回答1:

The equivalent C code looks like this:

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

Note that invalid_characters is a C string, ie. a null-terminated char array.



回答2:

The less well-known but extremely useful (and standard since C89 — meaning 'forever') functions in the C library provide the information in a single call. Actually, there are multiple functions — an embarrassment of riches. The relevant ones for this are:

7.21.5.3 The strcspn function

Synopsis

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

Description

The strcspn function computes the length of the maximum initial segment of the string pointed to by s1 which consists entirely of characters not from the string pointed to by s2.

Returns

The strcspn function returns the length of the segment.

7.21.5.4 The strpbrk function

Synopsis

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

Description

The strpbrk function locates the first occurrence in the string pointed to by s1 of any character from the string pointed to by s2.

Returns

The strpbrk function returns a pointer to the character, or a null pointer if no character from s2 occurs in s1.

The question asks about 'for each char in string ... if it is in list of invalid chars'.

With these functions, you can write:

size_t len = strlen(test);
size_t spn = strcspn(test, "invald");

if (spn != len) { ...there's a problem... }

Or:

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

Which is better depends on what else you want to do. There is also the related strspn() function which is sometimes useful (whitelist instead of blacklist).



回答3:

Assuming your input is a standard null-terminated C string, you want to use strchr:

#include <string.h>

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

If on the other hand your array is not null-terminated (i.e. just raw data), you'll need to use memchr and provide a size:

#include <string.h>

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


回答4:

use strchr function when dealing with C strings.

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

Here is an example of what you want to do.

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

Use memchr when dealing with memory blocks (as not null terminated arrays)

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/



回答5:

You want

strchr (const char *s, int c)

If the character c is in the string s it returns a pointer to the location in s. Otherwise it returns NULL. So just use your list of invalid characters as the string.



回答6:

strchr for searching a char from start (strrchr from the end):

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

  if (strchr(str, 'h') != NULL) {
      /* h is in str */
  }


回答7:

I believe the original question said:

a character belongs to a list/array of invalid characters

and not:

belongs to a null-terminated string

which, if it did, then strchr would indeed be the most suitable answer. If, however, there is no null termination to an array of chars or if the chars are in a list structure, then you will need to either create a null-terminated string and use strchr or manually iterate over the elements in the collection, checking each in turn. If the collection is small, then a linear search will be fine. A large collection may need a more suitable structure to improve the search times - a sorted array or a balanced binary tree for example.

Pick whatever works best for you situation.