Trabajar con cadenas

Manipular el contenido de una cadena.

La manipulación de cadenas es una tarea muy común en la vida diaria de un desarrollador. El desarrollador necesita realizar tareas como duplicar cadenas, transformarlas en mayúsculas o verificar si algún carácter corresponde a un tipo en especial. Para este tipo de tareas, esta biblioteca dispone de una serie de funciones cuyo uso no dista mucho de las ya desarrolladas en la Libc.

Duplicación de cadenas.

Si lo que se desea es duplicar cadenas, las funciones g_strdup y g_strndup resolverán esa necesidad. Las dos funciones realizan el mismo trabajo: duplican la cadena que se le ha pasado como parámetro. La diferencia radica en que la segunda limita el número de caracteres que devuelve a un número que le es indicado por un segundo parámetro de la función.

gchar * g_strdup (const gchar * cadena_para_duplicar );

gchar * g_strndup (const gchar * cadena_para_duplicar , gsize longitud_maxima);

Verificación de caracteres.

El título se refiere al conjunto de funciones capaces de responder a preguntas como: ¿Este carácter es un dígito? o ¿este carácter es una letra?... Este tipo de funciones es muy usado en el tratamiento de cadenas y su funcionamiento es muy simple. Estas funciones reciben un carácter y devuelven cierto o falso. La siguiente tabla explica cuáles son esas funciones y cuál es la verificación que realizan. Se recomienda la observación del prototipo de la función g_ascii_isalnum, usado como ejemplo para una mejor comprensión de la tabla, ya que todas las funciones comparten el mismo prototipo.

gboolean g_ascii_isalnum (gchar carácter );`

Tabla 6-3.1. Funciones de verificación de caracteres.

Nombre de función

Es cierto si...

g_ascii_isalnum

Es un carácter alfanumérico.

g_ascii_isalpha

Es un carácter del alfabeto.

g_ascii_iscntrl

Es un carácter de control.

g_ascii_isdigit

Es un dígito.

g_ascii_isgraph

Es un carácter imprimible y no es un espacio.

g_ascii_islower

Es una letra minúscula.

g_ascii_isprint

Es un carácter imprimible.

g_ascii_ispunct

Es un carácter de puntuación.

g_ascii_isspace

Es un espacio.

g_ascii_isupper

Es una letra mayúscula.

Copia y concatenación de cadenas.

Otra acción típica para el programador es la copia de una cadena o la concatenación de de múltiples cadenas. Para realizar esta tarea se puede utilizar la función g_stpcpy. Esta función desempeña la tarea de copiar una cadena que se le pase como parámetro a una cadena destino, también pasada como parámetro. Esta función tiene la particularidad de devolver un puntero a la última posición de la cadena destino, de tal modo que, si se quisiera concatenar cadenas, sólo se tendría que pasar el puntero devuelto por el primer g_stpcpy al segundo como si fuera el destino. Así el segundo g_stpcpy entendería que ha de copiar la segunda cadena al final de la primera que se ha copiado anteriormente y así sucesivamente. Siguiendo este método, se podría concatenar una cadena tras otra.

gchar * g_stpcpy (gchar * cadena_destino , const gchar * cadena_origen );

GString : la otra manera de ver una cadena.

GString es un TAD (tipo abstracto de datos) que implementa GLib. Este TAD es un buffer de texto que tiene la capacidad de expandirse, realojando memoria automáticamente, sin que el programador tenga que actuar. Esto es realmente útil para el trabajo con cadenas, porque cuando se reserva memoria para texto y, más adelante, es insuficiente, el programador tiene que tomarse la molestia de reservar más. Por eso GLib implementa GString, que facilita enormemente el manejo de cadenas sin necesidad de estar pendientes de su gestión de memoria.

Para empezar a estudiar este TAD, lo primero que se debe conocer es la estructura de datos sobre la que esta diseñada y después se estudiaran las funciones que interactúan con esa estructura.

   1                   struct GString
   2                   {
   3                       gchar  *str;                                      (1)
   4                       gsize len;                                        (2)
   5                       gsize allocated_len;
   6                   };

(1)

(2)

Ahora se ha observado cómo es la estructura GString. El siguiente paso será ver las funciones que trabajan sobre GString con el fin de sacarle el mayor partido a este tipo abstracto de datos.

Cómo se aloja una cadena con GString.

Alojar una cadena con GString es extremadamente sencillo e intuitivo. Para ello se utilizará la función g_string_new (), que tiene la forma:

GString * g_string_new (const gchar * cadena_inicial );

Esta función recibe como parámetro una cadena y devuelve la estructura GString. De este modo, dentro de la estructura GString, se tendrá toda la información y, como se puede observar, no se ha sido necesario realizar movimiento alguno para alojar memoria.

Ejemplo 6-3.1. Crear una cadena con GString.

   1 /* ejemplo del uso de g_string_new */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         
   8         GString *cadena ;
   9         
  10         cadena = g_string_new ("!Qué fácil es hacer una cadena!");
  11         
  12         g_print ("la cadena que hemos alojado : %s\n", cadena->str);
  13         g_print ("la longitud de la cadena es : %d\n", cadena->len);
  14         return 0;
  15 }

Como se puede ver en la ejecución de este ejemplo, la creación de una cadena con GString es muy sencilla. Pero, además, GLib proporciona otra función para crear cadenas. La sinopsis de esta función es:

GString * g_string_new_len (const gchar * cadena_inicial,
                            gssize longitud_inicial );

La ventaja que tiene el uso de g_string_new_len es que permite especificar una longitud inicial y esto trae consigo que la cadena introducida no tiene necesariamente que estar terminada con el carácter NULL ("\0") y, además, puede tener varios caracteres NULL embebidos dentro de la cadena en cuestión.

Cómo puedo liberar un GString

Siendo GString una estructura, lo suyo sería liberar uno a uno todos los campos pero, gracias a la implementación que ofrece GLib, se dispondrá de una función que ayuda con la liberación de memoria que se ha reservado con la creación de un GString. La sinopsis de esta función sería:

gchar * g_string_free (GString * cadena , gboolean liberar_contenido_cadena );

Con la función g_string_free, se podrá liberar el GString que se entrega como primer argumento a la función. Además, esta función también da la posibilidad de liberar o no la cadena que estaría dentro de GString. Y esto se conseguiría si como segundo parámetro se le pasara el booleano TRUE. En caso contrario, si se le pasara un booleano FALSE, la cadena de caracteres no sería liberada.

Añadir, insertar y borrar cadenas en un GString.

Con los conocimientos necesarios para crear y liberar este tipo de datos, ha llegado el momento de aprender a trabajar con la funciones que tratan la información que aloja y, para empezar, se aprenderá como añadir texto a una cadena creada como GString. A la hora de añadir texto, puede interesar añadir texto al final o al principio de la cadena y se podrá hacer con GString. Las funciones que se verán ahora son exactamente iguales, salvo que contienen las palabras append o prepend, que indican que la función añade el texto al final o al principio respectivamente.

GString * g_string_append (GString * cadena,
                           gchar * cadena_para_añadir_al_final );

GString * g_string_prepend (GString * cadena,
                            gchar * cadena_para_añadir_al_principio );

Estas son las primeras funciones para el añadido de texto que se repasarán. La primera, g_string_append, se encargará de añadir el texto pasado como parámetro al final de la cadena contenida dentro del GString y la segunda, g_string_prepend, se encargará de añadir el texto al principio.

Con el siguiente ejemplo, se demostrará el uso práctico de estas funciones.

Ejemplo 6-3.2. Añadir cadena a un GString.

   1 /* ejemplo del uso de g_string_append y g_string_prepend */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7 
   8         GString *cadena ;
   9         
  10         cadena = g_string_new ("*");
  11         cadena = g_string_append (cadena, "| texto añadido al final");
  12         cadena = g_string_prepend (cadena, "texto añadido al principio |");
  13         
  14         g_print ("\n%s\n", cadena->str);
  15         return 0;
  16 }

Una vez que se sabe añadir texto por delante y por detrás de la cadena contenida dentro del GString, el siguiente paso natural sería aprender cómo se pueden introducir datos dentro de las cadenas, es decir, insertar una cadena. En el caso que se tenga un GString con una cadena. Con la función g_string_insert se puede insertar, en la posición elegida, la cadena que desee. Como se puede observar, en la sinopsis de la función y en el siguiente ejemplo, Lo único que se debe hacer es indicar la posición en la cual se quiere insertar la cadena y la cadena que se insertará.

GString * g_string_insert (GString * cadena, gssize posicion,
                           gchar * cadena_para_insertar );

Ejemplo 6-3.3. Insertar una cadena a un GString.

   1 /* ejemplo del uso de g_string_insert */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         
   8         GString *cadena ;
   9         gchar *cadena_para_insertar = "muy muy ";
  10         
  11         cadena = g_string_new ("El día esta soleado");
  12         cadena = g_string_insert (cadena, 13, cadena_para_insertar);
  13         
  14         g_print ("\n%s\n", cadena->str);
  15         
  16         g_string_free (cadena, TRUE);
  17         return 0;     
  18 }

Con las funciones mostradas anteriormente, se puede añadir información a un GString. Si lo que se desea es borrar, se cuenta con la función g_string_erase. Sólo hay que indicar la posición desde la que quiere empezar a borrar y el número de caracteres que desea borrar desde esa posición.

GString * g_string_erase (GString * cadena, gssize posicion,
                          GString * numero_de_caracteres_que_desea_borrar );

Ejemplo 6-3.4. Borrar una cadena a un GString.

   1 /* ejemplo del uso de g_string_erase */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         
   8         GString *cadena ;
   9         
  10         cadena = g_string_new ("Esto es una cadena --esto sera borrado--");
  11         cadena = g_string_erase (cadena, 19, 21);
  12         
  13         g_print ("\n%s\n", cadena->str);
  14         g_string_free (cadena, TRUE);
  15         return 0;
  16 }

Introducir texto preformateado a un GString.

Esta es una de las aplicaciones más interesantes que se le puede dar a un GString. Este tipo de datos permite trabajar con texto preformateado, como cuando se trabaja con un printf. Esta opción siempre es interesante, pues una vez que se tenga ese texto dentro del GString, se podrán aprovechar las múltiples facetas que posee este tipo.

La siguiente función, g_string_printf, recordará a la ya conocida sprintf() de C estándar; la diferencia está en que el buffer tiene la capacidad de crecer automáticamente. Otra cosa a tener en cuenta en el uso de esta función es que cuando se usa, el contenido anterior existente (si existiese) es destruido.

void g_string_printf (GString * cadena , const gchar formato , ... );

Ejemplo 6-3.5. Crear texto preformateado con GString.

   1 /* ejemplo del uso de g_string_printf */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         
   8         GString *cadena ;
   9         gchar *frase = "lo bueno, si breve, dos veces bueno" ;
  10         gint numero = 7 ;
  11         
  12         cadena = g_string_new ("");
  13         g_string_printf (cadena, "FRASE TIPICA : %s\nNUMERO DE LA SUERTE : %d",
  14                          frase, numero);
  15         
  16         g_print ("%s\n",cadena->str);
  17         g_string_free (cadena, TRUE);
  18         return 0;       
  19 }

GLib también dispone de una función similar a la anterior. La única diferencia estriba en que esta función añade el texto preformateado. Es decir, si se tuviera un texto dentro del GString, el texto formateado se añadiría detrás del texto existente. Esto puede resultar útil en el sentido de que la anterior función destruía el contenido anterior y puede que eso no le convenga.

void g_string_append_printf (GString * cadena , const gchar formato , ... );

Ejemplo 6-3.6. Añadir texto preformateado con GString.

   1 /* ejemplo del uso de g_string_append_printf */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         
   8         GString *cadena ;
   9         gchar *frase = "lo bueno, si breve, dos veces bueno" ;
  10         gint numero = 7 ;
  11         
  12         cadena = g_string_new ("Línea ya existente\n");
  13         g_string_append_printf (cadena,
  14                                 "FRASE TIPICA : %s\nNUMERO DE LA SUERTE : %d",
  15                                 frase, numero);
  16         g_print ("%s\n",cadena->str);
  17         g_string_free (cadena, TRUE);
  18         return 0;     
  19 }

Otras funciones útiles para el manejo de GString.

En las secciones anteriores se han explicado las funciones más comunes con las que poder manejar una estructura del tipo GString, pero estas funciones no son las únicas que existen para trabajar con este tipo de datos. En la siguiente sección, se explicarán otras que, aunque no son tan fundamentales, pueden resultar útiles.

Para empezar, puede que no siempre sea de gran interés insertar o añadir una cadena y sólo se quiera trabajar con un carácter. Para ello se dispone de estas funciones que, aunque surten el mismo efecto que si se usase g_string_append y similares, con un sólo carácter, puede que estas funciones sirvan para facilitar la legibilidad del código en un momento dado.

GString * g_string_append_c (GString * cadena , gchar caracter );

GString * g_string_prepend_c (GString * cadena , gchar caracter);

GString * g_string_insert_c (GString * cadena, gssize posicion,
                             gchar * caracter );

Ejemplo 6-3.7. Añadir e insertar caracteres a un GString.

   1 /* ejemplo del uso de g_string_{insert|append|prepend}_c */
   2 #include <glib.h>
   3 
   4 int
   5 main ()
   6 {
   7         
   8         GString *cadena;
   9         gchar caracter ;
  10         
  11         cadena = g_string_new ("");
  12         
  13         caracter = 'c' ;
  14         cadena = g_string_append_c (cadena, caracter);
  15         caracter = 'a' ;
  16         cadena = g_string_prepend_c (cadena, caracter);
  17         caracter = 'b' ;
  18         cadena = g_string_insert_c (cadena, 1, caracter);
  19         
  20         g_print ("la cadena resultante es... %s\n",cadena->str);
  21         g_string_free (cadena, TRUE);
  22         return 0;     
  23 }

Otras acciones que pueden resultar interesantes son la capacidad de truncar un texto por el lugar que se desee y la capacidad de convertir todo el texto a mayúsculas o minúsculas. Pues para satisfacer este tipo de necesidades se dispone de g_string_truncate, cuya sintaxis se muestra a continuación.

GString * g_string_truncate (GString * cadena , gsize longitud );

longitud se refiere al número de caracteres desde el principio de la cadena que se desea permanezcan una vez terminada la función.

GString * g_string_up (GString * cadena );

GString * g_string_down (GString * cadena );

La primera función, g_string_up, es la que convierte a mayúsculas un texto íntegro del GString y la segunda, g_string_down la que lo convierte en minúsculas.

GQuarks.

Los Quarks son asociaciones entre una cadena de texto y un identificador numérico (gunint32). Ya sea proporcionando el GQuark o la cadena de texto es posible obtener la información relacionada el uno con el otro. Los Quarks son utilizados en los Datasets y en los Keyed Data List.

Para crear un Quark nuevo de una cadena de texto se usa g_quark_from_string () o g_quark_from_static_string (). Para encontrar la cadena de texto correspondiente a un GQuark se utiliza g_quark_to_string (). Y para encontrar el Quark de una cadena de texto se puede usar g_quark_try_string ().

GQuark g_quark_from_string (const gchar *string );

Obtiene el identificador GQuark de la cadena que se pase como parámetro. Si la cadena de texto no tiene asociado un GQuark, un nuevo GQuark es creado, usando una copia de la cadena de texto.

GQuark g_quark_from_static_string (const gchar *string );

Obtiene el identificador GQuark de una cadena de texto estática. Si la cadena de texto no tiene asociado un GQuark, un nuevo GQuark es creado, vinculándolo con la cadena.

Esta función es idéntica a g_quark_from_string () excepto que si un GQuark es creado la propia cadena de texto es usada en lugar que una copia. Esto ahorra memoria, pero solo puede usarse si la cadena de texto siempre existe. Esto puede usarse con cadenas de texto que están alojadas estáticamente en el programa principal, pero no con las alojadas en memoria en el módulo cargado dinámicamente.

const gchar * g_quark_to_string (GQuark quark );

Obtiene la cadena de texto asociada con un GQuark.

GQuark g_quark_try_string (const gchar * string );

Obtiene el GQuark asociado con la cadena de texto. Regresa el GQuark asociado con la cadena de texto, o 0 si no hay un GQuark asociado con la cadena de texto.

GQuark es usado junto con Keyed Data Lists y Datasets, que son listas para organizar elementos que son accedidos por medio de una cadena de texto o por medio de un identificador GQuark, y Datasets es utilizado para asociar grupos de datos con posiciones de memoria.


Volver a: GLib

Documentacion/Desarrollo/Glib/TrabajarConCadenas (última edición 2008-12-04 08:48:53 efectuada por localhost)