Disponible la nueva versión "donationware" 7.3 de OrganiZATOR
Descubre un nuevo concepto en el manejo de la información.
La mejor ayuda para sobrevivir en la moderna jungla de datos la tienes aquí.

Curso C++

[Home]  [Inicio]  [Índice]


9.3.1  Manejo de cadenas alfanuméricas


  Un "Parser" muy simple:

Se muestra el esqueleto de lo que puede ser una analizador que acepta una cadena alfanumérica almacenada en un buffer InBuff, y separa los contenidos numéricos de los alfabéticos.  Como entrada del ejemplo se utiliza una cadena codificada en el programa, pero nada impide que este buffer sea el resultado de datos leídos directamente desde el dispositivo estándar de entrada (teclado) o desde un fichero.

#include <iostream>        // Un parser muy simple

char* InBuff = "AEIOU12345bcdef67890GHIJK";  // Buffer de entrada

enum caracter {NONE, LETTER, NUMBER, TOKNUM, TOKWORD,
               WHITESPACE, UNKNOWN} chact, chant;
#define LEN 25             // longitud del buffer de entrada
#define LBUFF 50           // longitud del buffer de salida
char OutBuff[LBUFF];

int pbuff;
void limpiar();        // función auxiliar limpiar el buffer de salida
void mostrar();        // función auxiliar mostrar el buffer de salida

int main() {           // ===========
  int pos = 0;         // posición inicial
  limpiar();
  register char c;
  do {
    c = *(InBuff+pos);
    if (c >= '0' && c<= '9')      chact = NUMBER;
    else if (c >= 'A' && c<= 'Z') chact = LETTER;
    else if (c >= 'a' && c<= 'z') chact = LETTER;

    // cualquier otra condición de análisis
    else chact = UNKNOWN;
    if (chact != chant) {     // cambio de tipo
      mostrar(); limpiar();
      chant = chact;
    } else {                  // mismo tipo
    // cualquier computación adicional
    }
    *(OutBuff+pbuff) = c;     // actualizar buffer de salida

    ++pbuff; ++pos;           // incrementar punteros
  } while (pos < LEN);        // fin del análisis
  mostrar();                  // mostrar último contenido del buffer
  std::cout << "Terminado!!" << std::endl;
  return 0;
}

void limpiar() {      // limpiar buffer de salida
  for (int i=0; i<LBUFF; ++i) *(OutBuff+i) = '\0';
  pbuff =0;
  chant = NONE;
}
void mostrar() {      // mostrar resultado
  if (pbuff !=0) std::cout << OutBuff << std::endl;
}

Salida:

AEIOU
12345
bcdef
67890
GHIJK
Terminado!!

Comentario:

Los enumeradores chant y chact representan el tipo leído anterior y actual de cada bucle.  Los tipos carácter adoptan valores distintos según el tipo de carácter leído.

Esta versión distingue solo dos tipos (y los agrupa) LETTER y NUMBER (el tipo auxiliar NONE es para el principio de cada secuencia, cuando todavía no se ha leído ningún carácter anterior).  Pero puede ser fácilmente ampliada para reconocer otros tipos.  Por ejemplo mayúsculas, minúsculas, tokens que pueden estar embebidos en cadenas numéricas TOKNUM, por ejemplo la coma y el punto (123.456,78) o los signos + y - etc.

La función mostrar() se limita a mostrar en pantalla cada grupo encontrado, pero puede ser modificada para enviar el resultado a cualquier otro dispositivo (una matriz, un fichero intercalando separadores, etc).

También es muy fácil añadir una modificación para que considere un espacio como separador de tokens o que los ignore; que se detenga y lance un error si se encuentra un carácter no esperado (UNKNOWN), etc.