C/C++: Texto de consola con formato

La consola (o terminal) de Linux/Unix admite diferentes formatos de carácter como negrita, subrayado, colores, etc. Para aplicar los formatos hemos desarrollado una función que junto con una enumeración nos permitirá de forma sencilla aplicar formato a nuestros textos por consola. A continuación podéis ver el código común a las dos funciones:

// Carácter de escape para aplicar los estilos.
#define CHAR_ESC    (char) 27
// Tamaño mínimo de la cadena de formato.
#define FORMAT_SIZE 10

// Enumeración con los formato de texto a aplicar.
typedef enum {
  FRM_NORMAL = 0,     // Texto con formato normal.
  FRM_BOLD,           // Texto en negrita.
  FRM_DARK,           // Texto oscurecido.
  FRM_UNDERLINE = 4,  // Texto subyarado.
  FRM_REVERSE = 7,    // Texto seleccionado.
  FRM_STRIKED = 9,    // Texto tachado.
  FRM_BLACK = 30,     // Texto de color negro.
  FRM_RED,            // Texto de color rojo.
  FRM_GREEN,          // Texto de color verde.
  FRM_YELLOW,         // Texto de color amarillo.
  FRM_BLUE,           // Texto de color azul.
  FRM_MAGENTA,        // Texto de color magenta.
  FRM_CYAN,           // Texto de color ciano.
  FRM_WHITE,          // Texto de color blanco.
  FRM_BACK_RED = 41,  // Color de fondo rojo.
  FRM_BACK_GREEN,     // Color de fondo verde.
  FRM_BACK_YELLOW,    // Color de fondo amarillo.
  FRM_BACK_BLUE,      // Color de fondo azul.
  FRM_BACK_MAGENTA,   // Color de fondo magenta.
  FRM_BACK_CYAN,      // Color de fondo ciano.
  FRM_BACK_GREY       // Color de fondo gris.
} strformat;

En el código superior se definen las constantes a utilizar en las funciones. La enumeración strformat contiene los valores de formato que se pueden aplicar. Esta parte no tiene más misterios, pasemos ahora a ver la función de formato para C estándar:

/**
 * Establece el formato de texto a partir del valor recibido.
 * @param  formato  Formato de texto a aplicar.
 * @param  cadena   Cadena en la que escribir el formato.
 * @param  tam      Tamaño de la cadena de formato.
 * @return Cadena con el formato aplicado.
 */
char * strFormat(const strformat formato, char * cadena, size_t tam) {
  if (cadena && tam >= FORMAT_SIZE) {
    snprintf(cadena, tam, "%c[%im", CHAR_ESC, formato);
  }

  return cadena;
}

La función de C, devuelve el mismo array que recibe de esta forma podemos utilizarla dentro de funciones como printf() sin problemas de estar llenando la memoria de elementos duplicados. Como podéis observar, el código de la función es muy sencillo, tan sólo se limita a imprimir el carácter de escape y a continuación el código de formato. Tan sólo nos queda ver un ejemplo de su uso:

  ...
  char arcFormato[FORMAT_SIZE];

  printf("Este es un %s", strFormat2(FRM_BLUE, arcFormato, sizeof(arcFormato)));
  printf("text%sto ", strFormat2(FRM_UNDERLINE, arcFormato, sizeof(arcFormato)));
  printf("%scon ", strFormat2(FRM_BOLD, arcFormato, sizeof(arcFormato)));
  printf("%sformato", strFormat2(FRM_BACK_CYAN, arcFormato, sizeof(arcFormato)));
  printf("%s\n", strFormat2(FRM_NORMAL, arcFormato, sizeof(arcFormato)));
  ...

No obstante hay algunos inconvenientes. Por ejemplo, como se usa el mismo array debe hacerse una llamada por printf, ya que si no, no se actualizará el formato. Para solventar este y otros problemas, tenemos una versión para C++:

/**
 * Establece el formato de texto a partir del valor recibido.
 * @param  formato  Formato de texto a aplicar.
 * @return Cadena con el formato aplicado.
 */
string strFormat(const strformat formato) {
  char arcFormato[10];
  snprintf(arcFormato, sizeof(arcFormato), "%c[%im", CHAR_ESC, formato);
  return arcFormato;
}

En este caso, el array se crea y destruye con la función, y lo que obtenemos es una cadena copiada. Podéis observar que prácticamente hacemos lo mismo que en el método C. Ahora veamos el mismo ejemplo con esta función:

  ...
  printf("Este es un %tyext%sto%s sin %sformato%s\n",
         strFormat(FRM_BLUE).c_str(), strFormat(FRM_UNDERLINE).c_str(),
         strFormat(FRM_BOLD).c_str(), strFormat(FRM_BACK_CYAN).c_str(),
         strFormat(FRM_NORMAL).c_str());
  ...

Tanto la primera como la segunda función, producirán la siguiente salida por consola:

Este es un texto con formato

También te podría gustar...

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

El tiempo límite ha expirado. Por favor, recarga el CAPTCHA.