Recherche…


Classification des caractères lus dans un flux

#include <ctype.h>
#include <stdio.h>

typedef struct {
  size_t space;
  size_t alnum;
  size_t punct;
} chartypes;

chartypes classify(FILE *f) {
  chartypes types = { 0, 0, 0 };
  int ch;

  while ((ch = fgetc(f)) != EOF) {
    types.space += !!isspace(ch);
    types.alnum += !!isalnum(ch);
    types.punct += !!ispunct(ch);
  }

  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 contrôle)
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)


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow