Manipular el contenido de una cadena.
La manipulación de cadenas es 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 caracter corresponde a un tipo en
especial. Para este tipo de tareas, esta librería dispone de
una serie de funciones cuyo uso no dista mucho de las ya
desarrolladas en la Libc™.
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 ( | cadena_para_duplicar ) ; | |
const gchar * | cadena_para_duplicar ; |
gchar * g_strndup ( | cadena_para_duplicar , | |
| longitud_maxima ) ; | |
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 ( | caracter ) ; | |
Tabla 5. 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 podemos utilizar la función
g_stpcpy. Esta función desempeña la
tarea de copiar una cadena que nosotros le pasemos 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 hemos copiado anteriormente y así
sucesivamente. Siguiendo este método, se podría concatenar
una cadena tras otra.
gchar * g_stpcpy ( | cadena_destino , | |
| cadena_origen ) ; | |
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 nosotros reservamos memoria para texto
y, más adelante, se nos queda pequeña, 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 tenemos que conocer es la estructura de datos
sobre la que esta diseñada y después estudiaremos las
funciones que interactúan con esa estructura.
struct GString
{
gchar *str;
gsize len;
gsize allocated_len;
};
|
En este puntero a una cadena de caracteres es donde se
almacenará el contenido de la cadena que nosotros
especifiquemos. De este modo, si en algún momento se
necesita el contenido de la cadena, sólo es necesario
acudir a este campo.
|
|
Este campo hace referencia a la longitud total de la
cadena que está alojada en el campo str de
la estructura GString. De este modo, si en
str está alojada la cadena "hola", el campo
len contendrá el número 4.
|
Ahora ya sabemos 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 usaremos la función
g_string_new (), que tiene la forma:
GString * g_string_new ( | cadena_inicial ) ; | |
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, tendremos toda la
información y, si el lector se ha percatado, en la creación
de la cadena, nosotros no hemos tenido que realizar ningún
movimiento para alojar memoria.
Ejemplo 6. Crear una cadena con GString.
/* ejemplo del uso de g_string_new */
#include <glib.h>
main (){
GString *cadena ;
cadena = g_string_new ("!Qué fácil es hacer una cadena!");
g_print ("la cadena que hemos alojado : %s\n", cadena->str);
g_print ("la longitud de la cadena es : %d\n", cadena->len);
}
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™ nos
proporciona otra función para crear cadenas. La sinopsis de
esta función es:
GString * g_string_new_len ( | cadena_inicial , | |
| longitud_inicial ) ; | |
const gchar * | cadena_inicial ; |
gssize | longitud_inicial ; |
La ventaja que tiene el uso de
g_string_new_len es que nos permite
especificar una longitud inicial y esto trae consigo que la
cadena que introducimos no tiene necesariamente que estar
terminada con el caracter 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 nos ofrece
GLib™, disponemos de una función
que nos ayuda con la liberación de memoria que hemos
reservado con la creación de un GString. La
sinopsis de esta función sería:
gchar * g_string_free ( | cadena , | |
| liberar_contenido_cadena ) ; | |
GString * | cadena ; |
gboolean | liberar_contenido_cadena ; |
Con la función g_string_free, nosotros
podremos liberar el GString que le pasemos como
primer argumento a la función. Además, esta función también
nos 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 le pasásemos el booleano
TRUE. En caso contrario, si pasásemos
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, vamos aprender como se puede añadir texto a una
cadena creada como GString. A la hora de añadir
texto, nos puede interesar añadir texto al final o al
principio de la cadena y podemos hacerlo con
GString. Las funciones que pasaremos a ver
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 ( | cadena , | |
| cadena_para_añadir_al_final ) ; | |
GString * | cadena ; |
gchar * | cadena_para_añadir_al_final ; |
GString * g_string_prepend ( | cadena , | |
| cadena_para_añadir_al_principio ) ; | |
GString * | cadena ; |
gchar * | cadena_para_añadir_al_principio ; |
Estas son las primeras funciones para el añadido de texto
que vamos a ver. 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 encargara de
añadir el texto al principio.
Con el siguiente ejemplo, el lector entenderá el uso
práctico de estas funciones.
Ejemplo 7. Añadir cadena a un GString.
/* ejemplo del uso de g_string_append y g_string_prepend */
#include <glib.h>
main (){
GString *cadena ;
cadena = g_string_new ("*");
cadena = g_string_append (cadena, "| texto añadido al final");
cadena = g_string_prepend (cadena, "texto añadido al principio |");
g_print ("\n%s\n", cadena->str);
}
Una vez que el programador 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. Imagíne que tiene 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 puede
observar, en la sinopsis de la función y en el siguiente
ejemplo, Lo único que tiene que hacer es indicar la posición
en la que quiere insertar la cadena y la cadena que se
insertará.
GString * g_string_insert ( | cadena , | |
| posicion , | |
| cadena_para_insertar ) ; | |
GString * | cadena ; |
gssize | posicion ; |
gchar * | cadena_para_insertar ; |
Ejemplo 8. Insertar una cadena a un GString.
/* ejemplo del uso de g_string_insert */
#include <glib.h>
main (){
GString *cadena ;
gchar *cadena_para_insertar = "muy muy ";
cadena = g_string_new ("El día esta soleado");
cadena = g_string_insert (cadena, 13, cadena_para_insertar);
g_print ("\n%s\n", cadena->str);
g_string_free (cadena, TRUE);
}
Con las funciones mostradas anteriormente, podemos añadir
información a un GString. Si lo que deseamos es
borrar, tenemos 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 ( | cadena , | |
| posicion , | |
| numero_de_caracteres_que_desea_borrar ) ; | |
GString * | cadena ; |
gssize | posicion ; |
GString * | numero_de_caracteres_que_desea_borrar ; |
Ejemplo 9. Borrar una cadena a un GString.
/* ejemplo del uso de g_string_erase */
#include <glib.h>
main (){
GString *cadena ;
cadena = g_string_new ("Esto es una cadena --esto sera borrado--");
cadena = g_string_erase (cadena, 19, 21);
g_print ("\n%s\n", cadena->str);
g_string_free (cadena, TRUE);
}
Introducir texto preformateado a un GString.
Esta es una de las aplicaciones más interesantes que podemos
dar a un GString. Este tipo de datos nos
permite trabajar con texto preformateado, como cuando
trabajamos con un printf. Esta opción
siempre es interesante, pues una vez que tengamos ese texto
dentro del GString, podremos aprovecharnos de
las múltiples facetas que posee este tipo.
La siguiente función, g_string_printf,
recordará al lector 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 ( | cadena , | |
| formato , | |
| ... ) ; | |
GString * | cadena ; |
const gchar | formato ; |
| ... ; |
Ejemplo 10. Crear texto preformateado con GString.
/* ejemplo del uso de g_string_printf */
#include <glib.h>
main (){
GString *cadena ;
gchar *frase = "lo bueno, si breve, dos veces bueno" ;
gint numero = 7 ;
cadena = g_string_new ("");
g_string_printf (cadena, "FRASE TIPICA : %s\nNUMERO DE LA SUERTE : %d",
frase, numero);
g_print ("%s\n",cadena->str);
g_string_free (cadena, TRUE);
}
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 tuvieramos un texto dentro del GString, el
texto formateado se añadiría detrás del texto
existente. Esto le 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 ( | cadena , | |
| formato , | |
| ... ) ; | |
GString * | cadena ; |
const gchar | formato ; |
| ... ; |
Ejemplo 11. Añadir texto preformateado con GString.
/* ejemplo del uso de g_string_append_printf */
#include <glib.h>
main (){
GString *cadena ;
gchar *frase = "lo bueno, si breve, dos veces bueno" ;
gint numero = 7 ;
cadena = g_string_new ("Línea ya existente\n");
g_string_append_printf (cadena, "FRASE TIPICA : %s\nNUMERO DE LA SUERTE : %d",
frase, numero);
g_print ("%s\n",cadena->str);
g_string_free (cadena, TRUE);
}
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 al programador no le interese
insertar o añadir una cadena y sólo quiera trabajar con un
carácter. Para ello dispone de estas funciones que, aunque
surten el mismo efecto que si usase
g_string_append y similares, con un
sólo carácter, puede que estas funciones le sirvan para dar
más legibilidad a su código en un momento dado.
GString * g_string_append_c ( | cadena , | |
| caracter ) ; | |
GString * | cadena ; |
gchar | caracter ; |
GString * g_string_prepend_c ( | cadena , | |
| caracter) ; | |
GString * | cadena ; |
gchar | caracter; |
GString * g_string_insert_c ( | cadena , | |
| posicion , | |
| caracter ) ; | |
GString * | cadena ; |
gssize | posicion ; |
gchar * | caracter ; |
Ejemplo 12. Añadir e insertar caracteres a un GString.
/* ejemplo del uso de g_string_{insert|append|prepend}_c */
#include <glib.h>
main (){
GString *cadena;
gchar caracter ;
cadena = g_string_new ("");
caracter = 'c' ;
cadena = g_string_append_c (cadena, caracter);
caracter = 'a' ;
cadena = g_string_prepend_c (cadena, caracter);
caracter = 'b' ;
cadena = g_string_insert_c (cadena, 1, caracter);
g_print ("la cadena resultante es... %s\n",cadena->str);
g_string_free (cadena, TRUE);
}
Otras acciones que pueden interesarle son la capacidad de
truncar un texto por el lugar que usted desee y la capacidad
de convertir todo el texto a mayúsculas o minúsculas. Pues
para este tipo de necesidades usted dispone de
g_string_truncate, cuya sintaxis se
muestra a continuación.
GString * g_string_truncate ( | cadena , | |
| longitud ) ; | |
GString * | cadena ; |
gsize | longitud ; |
longitud se refiere al número de caracteres desde el principio de la cadena que desea que permanezcan una vez terminada la función.
GString * g_string_up ( | cadena ) ; | |
GString * g_string_down ( | 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.