web-dev-qa-db-fra.com

En C - vérifier si un caractère existe dans un tableau de caractères

J'essaie de vérifier si un caractère appartient à une liste/tableau de caractères invalides.

Venant d'un arrière-plan Python, je pouvais simplement dire:

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

Comment puis-je faire cela avec des tableaux de caractères C normaux?

46
Amarok

Le code C équivalent ressemble à ceci:

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

Notez que invalid_characters est une chaîne C, c'est-à-dire. un tableau char terminé par null.

31
RichieHindle

Les fonctions moins connues mais extrêmement utiles (et standard depuis C89 - signifiant "pour toujours") de la bibliothèque C fournissent les informations en un seul appel. En fait, il y a de multiples fonctions - un embarras de richesse. Les éléments pertinents pour cela sont:

7.21.5.3 La fonction strcspn

Synopsis

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

La description

La fonction strcspn calcule la longueur du segment initial maximal de la chaîne pointée par s1 qui est entièrement composée de caractères ne provenant pas de la chaîne pointée par s2.

Résultats

La fonction strcspn renvoie la longueur du segment.

7.21.5.4 La fonction strpbrk

Synopsis

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

La description

La fonction strpbrk localise la première occurrence dans la chaîne pointée par s1 de n'importe quel caractère de la chaîne pointée par s2.

Résultats

La fonction strpbrk renvoie un pointeur sur le caractère ou un pointeur nul si aucun caractère de s2 n'apparaît dans s1.

La question demande "pour chaque caractère dans la chaîne ... s'il est dans la liste des caractères invalides".

Avec ces fonctions, vous pouvez écrire:

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

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

Ou:

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

Ce qui est mieux dépend de ce que vous voulez faire d'autre. Il y a aussi la fonction strspn() associée qui est parfois utile (liste blanche au lieu de liste noire).

43
Jonathan Leffler

En supposant que votre entrée est une chaîne C standard terminée par un caractère nul, vous souhaitez utiliser strchr :

#include <string.h>

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

Si d'un autre côté votre tableau n'est pas terminé par un caractère nul (c'est-à-dire uniquement des données brutes), vous devrez utiliser memchr et fournir une taille:

#include <string.h>

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

utilisez la fonction strchr pour traiter les chaînes C.

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

Voici un exemple de ce que vous voulez faire.

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

Utilisez memchr lorsque vous traitez avec des blocs de mémoire (comme des tableaux non terminés par null)

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
Tom

Tu veux

strchr (const char * s, int c)

Si le caractère c est dans la chaîne s, il renvoie un pointeur vers l'emplacement en s. Sinon, il renvoie NULL. Il vous suffit donc d'utiliser votre liste de caractères non valides comme chaîne.

4
Keith Smith

strchr pour rechercher un caractère depuis le début (strrchr depuis la fin):

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

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

Je pense que la question initiale disait:

un caractère appartient à une liste/tableau de caractères invalides

et pas:

appartient à une chaîne terminée par null

ce qui, si c'était le cas, alors strchr serait en effet la réponse la plus appropriée. Si, cependant, il n'y a pas de terminaison nulle pour un tableau de caractères ou si les caractères sont dans une structure de liste, alors vous devrez soit créer une chaîne terminée par null et utiliser strchr ou itérer manuellement sur les éléments dans la collection, en les vérifiant tour à tour. Si la collection est petite, une recherche linéaire conviendra. Une grande collection peut nécessiter une structure plus appropriée pour améliorer les temps de recherche - un tableau trié ou un arbre binaire équilibré par exemple.

Choisissez ce qui fonctionne le mieux pour votre situation.

1
Skizz