• Aucun résultat trouvé

Classification des caractères d'une chaîne

Dans le document Apprenez le langage C (Page 33-38)

return types; }

La fonction de classify lit les caractères d'un flux et compte le nombre d'espaces, les caractères alphanumériques et les signes de ponctuation. Cela évite plusieurs écueils.

Lors de la lecture d'un caractère dans un flux, le résultat est enregistré sous la forme d'un int , car sinon il y aurait une ambiguïté entre la lecture de EOF (marqueur de fin de fichier) et un caractère ayant le même modèle de bit.

Les fonctions de classification des caractères (par exemple, isspace ) s'attendent à ce que leur argument soit représentable en tant que caractère unsigned char ou en tant que valeur de la macro EOF . Puisque c'est exactement ce que retourne fgetc , il n'y a pas besoin de conversion ici.

La valeur de retour des fonctions de classification de caractères ne fait que distinguer zéro (signifiant false ) et non nul (ce qui signifie true ). Pour compter le nombre d'occurrences, cette valeur doit être convertie en 1 ou 0, ce qui se fait par la double négation, !! .

Classification des caractères d'une chaîne

#include <ctype.h> #include <stddef.h> typedef struct {

size_t space; size_t alnum; size_t punct; } chartypes;

chartypes classify(const char *s) { chartypes types = { 0, 0, 0 }; const char *p;

for (p= s; p != '\0'; p++) {

types.space += !!isspace((unsigned char)*p); types.alnum += !!isalnum((unsigned char)*p); types.punct += !!ispunct((unsigned char)*p); }

return types; }

La fonction de classify examine tous les caractères d'une chaîne et compte le nombre d'espaces, les caractères alphanumériques et les signes de ponctuation. Cela évite plusieurs écueils.

Les fonctions de classification des caractères (par exemple, isspace ) s'attendent à ce que leur argument soit représentable en tant que caractère unsigned char ou en tant que valeur de la macro EOF .

L'expression *p est de type char et doit donc être convertie pour correspondre à la formulation ci-dessus.

Le char type est défini comme équivalent soit signed char ou unsigned char . •

Lorsque char est équivalent à unsigned char , il n'y a pas de problème, puisque toutes les valeurs possibles du char type est représentable comme unsigned char .

Lorsque char est équivalent au caractère signed char , il doit être converti en caractère unsigned char avant d'être transmis aux fonctions de classification des caractères. Et bien que la valeur du caractère puisse changer à cause de cette conversion, c'est exactement ce à quoi ces fonctions s'attendent.

La valeur de retour des fonctions de classification de caractères ne fait que distinguer zéro (signifiant false ) et non nul (ce qui signifie true ). Pour compter le nombre d'occurrences, cette valeur doit être convertie en 1 ou 0, ce qui se fait par la double négation, !! .

introduction

L'en-tête ctype.h fait partie de la bibliothèque standard C. Il fournit des fonctions pour classer et convertir les caractères.

Toutes ces fonctions prennent un paramètre, un int qui doit être soit EOF, soit représentable en tant que caractère non signé.

Les noms des fonctions de classement sont préfixés par 'is'. Chacun renvoie une valeur non nulle entière (TRUE) si le caractère qui lui est transmis satisfait à la condition associée. Si la condition n'est pas satisfaite, la fonction retourne une valeur zéro (FALSE).

Ces fonctions de classification fonctionnent comme indiqué, en supposant que les paramètres régionaux C par défaut:

int a; int c = 'A';

a = isalpha(c); /* Checks if c is alphabetic (A-Z, a-z), returns non-zero here. */

a = isalnum(c); /* Checks if c is alphanumeric (A-Z, a-z, 0-9), returns non-zero here. */ a = iscntrl(c); /* Checks is c is a control character (0x00-0x1F, 0x7F), returns zero here. */ a = isdigit(c); /* Checks if c is a digit (0-9), returns zero here. */

a = isgraph(c); /* Checks if c has a graphical representation (any printing character except space), returns non-zero here. */

a = islower(c); /* Checks if c is a lower-case letter (a-z), returns zero here. */

a = isprint(c); /* Checks if c is any printable character (including space), returns non-zero here. */

a = isupper(c); /* Checks if c is a upper-case letter (a-z), returns zero here. */ a = ispunct(c); /* Checks if c is a punctuation character, returns zero here. */ a = isspace(c); /* Checks if c is a white-space character, returns zero here. */

a = isupper(c); /* Checks if c is an upper-case letter (A-Z), returns non-zero here. */

a = isxdigit(c); /* Checks if c is a hexadecimal digit (A-F, a-f, 0-9), returns non-zero here. */

C99

a = isblank(c); /* Checks if c is a blank character (space or tab), returns non-zero here. */

Il y a deux fonctions de conversion. Ceux-ci sont nommés en utilisant le préfixe «to». Ces

fonctions prennent le même argument que celles ci-dessus. Cependant, la valeur de retour n'est pas un simple zéro ou non nul, mais l'argument passé a changé d'une certaine manière.

Ces fonctions de conversion fonctionnent comme indiqué, en supposant la locale C par défaut: int a;

int c = 'A';

/* Converts c to a lower-case letter (a-z).

* If conversion is not possible the unchanged value is returned. * Returns 'a' here.

*/

a = tolower(c);

/* Converts c to an upper-case letter (A-Z).

* If conversion is not possible the unchanged value is returned. * Returns 'A' here.

*/

a = toupper(c);

Les informations ci-dessous sont extraites de la mise en correspondance de cplusplus.com sur la manière dont l'ensemble ASCII à 127 caractères d'origine est pris en compte par chacune des fonctions de type classification (a • indique que la fonction renvoie une valeur non nulle pour ce caractère)

Valeurs

ASCII personnages iscntrl isblank isspace isupper

est plus bas

isalpha isdigit isxdigit isalnum ispunct Isgraph isprint

0x00 .. 0x08

NUL, (autres codes de

Valeurs

ASCII personnages iscntrl isblank isspace isupper

est plus bas

isalpha isdigit isxdigit isalnum ispunct Isgraph isprint

0x09 onglet ('\ t') • • •

0x0A .. 0x0D

(codes de contrôle d'espaces

blancs: '\ f', '\ v', '\ n', '\ r') 0x0E ..

0x1F (autres codes de contrôle)

0x20 espace (' ') • • • 0x21 .. 0x2F ! "# $% & '() * +, -. / 0x30 .. 0x39 0123456789 0x3a .. 0x40 :; <=>? @ 0x41 .. 0x46 A B C D E F 0x47 .. 0x5A GHIJKLMNOPQRSTUVWXYZ 0x5B .. 0x60 [] ^ _ ` 0x61 .. 0x66 a B c d e F 0x67 .. 0x7A ghijklmnopqrstuvwxyz 0x7B .. 0x7E {} ~ bar 0x7F (DEL) •

Lire - classification et conversion des personnages en ligne: https://riptutorial.com/fr/c/topic/6846/-ctype-h----classification-et-conversion-des-personnages

Chapitre 3: Affirmation

Introduction

Une assertion est un prédicat que la condition présentée doit être vraie au moment où l'assertion est rencontrée par le logiciel. Les plus simples sont les assertions simples , validées au

moment de l'exécution. Cependant, les assertions statiques sont vérifiées au moment de la compilation.

Syntaxe

affirmer (expression) •

static_assert (expression, message) •

_Static_assert (expression, message) •

Paramètres

Paramètre Détails

expression expression de type scalaire.

message chaîne littérale à inclure dans le message de diagnostic.

Remarques

Les deux assert et static_assert sont des macros définies dans assert.h .

La définition de assert dépend de la macro NDEBUG qui n'est pas définie par la bibliothèque standard. Si NDEBUG est défini, assert est un no-op:

#ifdef NDEBUG

# define assert(condition) ((void) 0) #else

# define assert(condition) /* implementation defined */ #endif

L'opinion varie selon que NDEBUG doit toujours être utilisé pour les compilations de production. Le pro-camp soutient que assert appels abort et les messages d'affirmation ne sont pas utiles pour les utilisateurs finaux, de sorte que le résultat n'est pas utile à l' utilisateur. Si vous avez des conditions fatales à vérifier dans le code de production, vous devez utiliser les if/else ordinaires et exit ou quick_exit pour terminer le programme. Contrairement à l’ abort , elles permettent au programme de faire du nettoyage (via des fonctions enregistrées avec atexit ou at_quick_exit ).

Le con camp fait valoir que assert appels ne doivent jamais tirer dans le code de production, mais si elles le font, la condition est cochée, il y a quelque chose de mal et de façon

spectaculaire le programme se conduisent mal pire si l' exécution se poursuit. Par

conséquent, il est préférable d’avoir des assertions actives dans le code de la production car si elles se déclenchent, l’enfer est déjà déchaîné.

Une autre option consiste à utiliser un système d'assertions maison qui exécute toujours la vérification mais gère les erreurs différemment entre le développement (lorsque l' abort est approprié) et la production (où une «erreur interne inattendue - veuillez contacter le support technique» peut être plus appropriée).

static_assert développe en _Static_assert qui est un mot clé. La condition est vérifiée au moment de la compilation, la condition doit donc être une expression constante. Il n'est pas nécessaire que cela soit traité différemment entre le développement et la production.

Examples

Dans le document Apprenez le langage C (Page 33-38)