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