Buscar..


Clasificación de caracteres leídos de una secuencia

#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 función de classify lee caracteres de una secuencia y cuenta el número de espacios, caracteres alfanuméricos y puntuación. Evita varias trampas.

  • Cuando se lee un carácter de un flujo, el resultado se guarda como un int , ya que de lo contrario habría una ambigüedad entre la lectura de EOF (el marcador de fin de archivo) y un carácter que tiene el mismo patrón de bits.
  • Las funciones de clasificación de caracteres (por ejemplo, isspace ) esperan que su argumento se pueda representar como un unsigned char , o el valor de la macro EOF . Dado que esto es exactamente lo que devuelve el fgetc , no hay necesidad de conversión aquí.
  • El valor de retorno de las funciones de clasificación de caracteres solo distingue entre cero (que significa false ) y distinto de cero (que significa true ). Para contar el número de ocurrencias, este valor se debe convertir a 1 o 0, lo que se hace con la negación doble, !! .

Clasificar caracteres de una cadena

#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 función de classify examina todos los caracteres de una cadena y cuenta el número de espacios, caracteres alfanuméricos y signos de puntuación. Evita varias trampas.

  • Las funciones de clasificación de caracteres (por ejemplo, isspace ) esperan que su argumento se pueda representar como un unsigned char , o el valor de la macro EOF .
  • La expresión *p es de tipo char y, por lo tanto, debe convertirse para que coincida con el texto anterior.
  • El tipo char se define como equivalente a signed char o unsigned char .
  • Cuando char es equivalente a un unsigned char , no hay problema, ya que cada valor posible del tipo char se puede representar como un unsigned char .
  • Cuando char es equivalente a signed char , se debe convertir a unsigned char antes de pasar a las funciones de clasificación de caracteres. Y aunque el valor del personaje puede cambiar debido a esta conversión, esto es exactamente lo que estas funciones esperan.
  • El valor de retorno de las funciones de clasificación de caracteres solo distingue entre cero (que significa false ) y distinto de cero (que significa true ). Para contar el número de ocurrencias, este valor se debe convertir a 1 o 0, lo que se hace con la negación doble, !! .

Introducción

El encabezado ctype.h es una parte de la biblioteca C estándar. Proporciona funciones para clasificar y convertir personajes.

Todas estas funciones toman un parámetro, un int que debe ser EOF o representable como un carácter sin signo.

Los nombres de las funciones de clasificación tienen el prefijo 'es'. Cada uno devuelve un valor entero no nulo (VERDADERO) si el carácter que se le pasa satisface la condición relacionada. Si la condición no se cumple, la función devuelve un valor cero (FALSO).

Estas funciones de clasificación funcionan como se muestra, asumiendo la configuración regional C predeterminada:

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. */

Hay dos funciones de conversión. Estos se nombran usando el prefijo 'to'. Estas funciones toman el mismo argumento que las anteriores. Sin embargo, el valor de retorno no es un simple cero o no cero, pero el argumento pasado cambió de alguna manera.

Estas funciones de conversión funcionan como se muestra, asumiendo la configuración regional C predeterminada:

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);

La información a continuación se cita en cplusplus.com, que muestra cómo el conjunto ASCII de 127 caracteres original es considerado por cada una de las funciones de tipo de clasificación (a • indica que la función no es cero para ese carácter)

Valores ASCII caracteres iscntrl está en blanco espacio de emisión isupper es bajo isalfa isigigito isxdigit Isalnum ispunct isgraph impresión
0x00 .. 0x08 NUL, (otros códigos de control)
0x09 pestaña ('\ t')
0x0A .. 0x0D (códigos de control de espacios en blanco: '\ f', '\ v', '\ n', '\ r')
0x0E .. 0x1F (otros códigos de control)
0x20 espacio (' ')
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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow