Definición
Una cadena de caracteres es un array unidimensional de tipo char terminado con un carácter nulo ('\0').
* Cualquier cadena de caracteres entre comillas dobles es considerada por el compilador como una constante tipo array de caracteres. El compilador cuenta el número de caracteres para saber cuanta memoria va a necesitar para su almacenamiento. Ejemplo.
char m1[] = "Cosa";
char m1[] = { 'C', 'o', 's', 'a', '\0' }; /* ambas declaraciones son equivalentes */ /* m1 es un puntero constante al primer
elemento del array */
char *m2 = "Cosa"; /* m2 es una variable de tipo puntero */ char m2[10] = "Lindo pez";
char m3[50] = "Bocineta";
/* los caracteres restantes se ponen a cero */
* Arrays de cadenas de caracteres: Se utiliza un subíndice para acceder a las distintas cadenas del array.
char *cadenas[5] = { "Sumo con precisión", "Almaceno datos",
"Dibujo gráficos", "Ejecuto programas", "Domino el C" };
/* este array no es rectangular, ya que sus filas no son todas de la misma longitud */
char cadenas[5][19]; /* este array sí es rectangular */
* Entrada de cadenas de caracteres.
- Preparación de espacio para su almacenamiento (declaración).
- Empleo de una función de entrada para capturar la cadena. Se suelen utilizar las funciones scanf() y gets().
La función gets() captura una cadena introducida por el dispositivo de entrada estándar del sistema. Esta función lee caracteres hasta que encuentra el carácter '\n'. Entonces el ordenador toma todos los caracteres menos el carácter de nueva-línea, que se reemplaza por el carácter '\0'.
Ejemplo:
char nombre[20]; /* reservamos espacio para 20 caracteres */ gets(nombre);
La función gets() tiene dos retornos posibles:
- Si todo va bien devuelve la dirección de la cadena leída.
- Si hay algo equivocado o la función encuentra un carácter EOF, devuelve una dirección cero o NULL, definida en <stdio.h> como cero.
Ejemplo:
/* mientras la lectura sea correcta */ while (gets(nombre) != NULL) {
.
. /* se pueden crear este tipo de . sentencias */
}
La función scanf() permite leer una cadena de caracteres mediante el especificador %s. Esta función devuelve un valor entero igual al número de items leídos. Si hay un error o se encuentra un carácter EOF, scanf() devuelve éste último.
Ejemplo:
char nombre[15]; /* reservamos espacio */ scanf("%s", nombre);
* Salida de cadenas de caracteres.
Las dos funciones básicas de salida de cadenas son puts() y printf(), cuyos prototipos también están incluidos en <stdio.h>.
La función puts() sólo necesita un argumento, que es un puntero a una cadena de caracteres. Esta función sustituye el carácter nulo final por el carácter '\n' y lo envía a la salida estándar.
Ejemplo
char mensaje[] = "Hola mundo"; puts(mensaje);
La función printf() también toma un puntero a una cadena como argumento, pero no añade el carácter de nueva-línea al final de la cadena automáticamente. Esta función permite combinar varias cadenas en una sola línea de ejecución.
Ejemplo:
#include <stdio.h>
#define MSJ "Fantástico" int main() {
char *nombre = "Juan";
printf("Bien, %s, %s.\n", nombre, MSJ); return 0;
Funciones de cadenas de caracteres. * Prototipos en <string.h>.
* Longitud de una cadena.
int strlen(char *);
La función strlen() (string length) calcula la longitud de una cadena de caracteres, excluyendo el carácter de fin de cadena.
* Concatenación de cadenas.
char *strcat(char *, char *);
La función strcat() (string concatenation) toma dos cadenas como argumentos, añade una copia de la segunda cadena al final de la primera y hace que esta versión combinada sea la nueva cadena primera. La segunda cadena no se altera. strcat() devuelve la dirección de la primera cadena.
Esta función no comprueba si la primera cadena dispone de espacio suficiente para almacenar la concatenación de ambas cadenas.
Ejemplo: #include <stdio.h> #include <string.h> #define MAX_LONG 80 int main() { char flor[MAX];
char apendice[] = " es una flor bonita"; puts("¿Cuál es tu flor favorita?");
gets(flor); if ((strlen(apendice) + strlen(flor) + 1) <= MAX_LONG) { strcat(flor, apendice); puts(flor); } else
puts("No hay espacio suficiente."); return 0;
}
* Comparación de cadenas.
int strcmp(char *, char *);
La función strcmp() (string comparison) compara dos cadenas carácter a carácter. Si las dos cadenas son iguales la función devuelve cero, pero si son distintas strcmp() devuelve la diferencia entre los dos primeros caracteres que son distintos.
strcmp() compara cadenas almacenadas en arrays de diferente tamaño.
char *cad1 = "Melocomotón"; char *cad2 = "Melocomotón";
if (cad1 == cad2) /* ¡¡¡Error!!! */
... /* estamos comparando punteros */ if (strcmp(cad1, cad2) == 0) /* correcto */
... Ejemplo: strcmp("HOLA", "HOLB") /* -1 */ strcmp("HOLB", "HOLA") /* 1 */ strcmp("HOLA", "HOL") /* 65 */ strcmp("HOL", "HOLA") /* -65 */ * Copia de cadenas. strcpy(char, char);
La función strcpy() (string copy) copia los caracteres de la cadena que se pasa como segundo argumento en la cadena que se pasa como primer argumento.
char *pt1 = "Hola, campeón"; char *pt2;
pt2 = pt1; /* sólo copia la dirección de la cadena en pt2 */
En esta función no es incumbencia del ordenador la preparación de espacio para la copia en el array de destino; este detalle queda bajo la completa responsabilidad del programador.
Ejemplo:
#include <stdio.h> #include <string.h>
int main() {
char *pt1 = "Hola, campeón";
char pt2[20]; /* siempre hay que
reservar memoria */ strcpy(pt2, pt1); /* se copian los
caracteres de la cadena apuntada por
pt1 en pt2 */
printf("Cadena origen: %s.\n", pt1); printf("Cadena destino: %s.\n", pt2); return 0;
Ficheros.
Definición.
Un fichero puede definirse como un almacenamiento de datos, generalmente en disco, con un nombre.
Funciones básicas * Apertura de un fichero.
Antes de empezar a trabajar con un fichero es necesario abrirlo. La función fopen() utiliza dos parámetros.
FILE *fopen(char *, char *);
El primer parámetro es el nombre del fichero a abrir, en formato del S.O. El segundo parámetro es una cadena de caracteres que describe el uso al que se va a destinar el fichero:
"r" Lectura (read).
"w" Escritura (write). "a" Apéndice (append).
Algunos sistemas ofrecen posibilidades adicionales, como añadir la letra t si el fichero es de texto ("rt", "wt", "at") o la letra b si el fichero es binario ("rb", "wb", "ab").
Valor de retorno de fopen():
- Puntero a la estructura del fichero, que debe asignarse a una variable de este tipo para poder acceder al fichero a través de esa variable.
- NULL si se ha producido un error al intentar abrir el fichero. Ejemplo: #include <stdio.h> int main() { FILE *in; int ch; if ((in = fopen("TEST.TXT", "r")) != NULL) {
while ((ch = getc(in)) != EOF) putc(ch, stdout);
/* equivale a putchar(ch); */ fclose(in);
} else
puts("No se puede abrir \"test\"."); return 0;
* Cierre de un fichero.
La función fclose() acepta como argumento el
puntero al fichero. También realiza el vaciado del buffer, que podría haber quedado parcialmente
lleno en el momento de cerrar el fichero. int fclose(FILE *);
Valor de retorno de fclose():
- NULL si el cierre se ha realizado satisfactoriamente.
- EOF si se ha producido un error al intentar cerrar el fichero.
* Entrada/salida básica.
La función getc() captura un carácter de un fichero, cuyo puntero se especifica como parámetro de la función.
int getc(FILE *);
La función putc() envía el carácter especificado en el primer parámetro al fichero cuyo puntero se especifica en el segundo parámetro.
Entrada/salida con formato.
Las funciones fprintf() y fscanf() se comportan exactamente igual que printf() y scanf(), excepto que requieren un argumento adicional para apuntar al fichero correspondiente.
Ejemplo:
FILE *ent, *sal; int entero;
float real;
if ((ent = fopen("ENTRADA.TXT", "rt")) == NULL)
puts("Error al abrir ENTRADA.TXT."); else
if ((sal = fopen("SALIDA.TXT", "at")) == NULL) {
puts("Error al abrir SALIDA.TXT."); fclose(ent);
/* los ficheros siempre deben cerrarse */
} else {
fscanf(ent, "%d %f", &entero, &real); fprintf(sal, "Num1: %d, Num2: %f.\n",
entero, real); fclose(ent);
fclose(sal);
/* fcloseall() cierra todos los ficheros */
Entrada/salida de cadenas de caracteres. La función fgets() utiliza tres argumentos:
- Puntero al lugar de destino de la cadena a leer. - Longitud máxima de la cadena.
- Puntero al fichero.
char *fgets(char *, int, FILE *); Esta función se detiene cuando lee el carácter '\n' o ha leído el máximo de caracteres indicado en el segundo argumento menos uno. En cualesquiera de los casos, se añade un '\0' al final de la cadena. Además, fgets() mantiene el carácter de nueva-línea.
Al igual que gets(), fgets() devuelve NULL cuando encuentra un carácter EOF, lo cual permite comprobar si se ha alcanzado el final del fichero.
La función fputs() funciona de modo similar a puts(). Esta función no copia el carácter '\0' al final de la cadena y tampoco añade un carácter '\n' en el fichero de salida.
Acceso aleatorio.
* La función fseek() permite tratar los ficheros como arrays, moviéndose directamente a un byte determinado del fichero abierto previamente por fopen().
Argumentos de fseek(): - Puntero al fichero.
- Desplazamiento desde el punto de referencia. - Modo que indica el punto de referencia.
int fseek(FILE *, long, int);
Modo Número Origen del desplazamiento
SEEK_SET 0 Comienzo del fichero.
SEEK_CUR 1 Posición actual.
SEEK_END 2 Fin del fichero.
Valor de retorno de fseek(): - Si no ha habido error 0.
- En caso de error -1. Un error común consiste en intentar avanzar más allá de los límites del fichero.
Ejemplo:
#include <stdio.h> #include <stdlib.h>
int main() { /* imprime un fichero de texto al revés */
FILE *fp;
long despl = 0L; /* cero "largo" */ char ch;
if ((fp = fopen("texto.txt", "r")) == NULL) {
puts("El fichero no puede abrirse."); exit(1); /* se aborta el programa con
un código de error */ }
fseek(fp, --despl, SEEK_END);
/* sitúa el puntero justo antes del fin de fichero (EOF) */
while ((ch = getc(fp)) != EOF) { putchar(ch);
fseek(fp, --despl, SEEK_END);
/* mueve el puntero un byte hacia atrás */
}
fclose(fp);
/* los ficheros siempre deben cerrarse */ return 0;
Bibliografía
• Aprendiendo C. Tercera Edición Revisada y Ampliada. J.M. Rodríguez, J. Galindo. Servicio de
Publicaciones de la UCA, 2006.
• Ejercicios Resueltos de Programación C. P.J.
Sánchez, J. Galindo, I. Turias, I. Lloret. Servicio de Publicaciones de la UCA, 1997.
• Turbo C/C++. Manual de Referencia. H. Schildt.
McGraw-Hill, 1993.
• C. Guía de Autoenseñanza. H. Schildt.
McGraw-Hill, 1994.
• El lenguaje de Programación C. Segunda Edición.
B.W. Kernighan, D.M. Ritchie. Prentice Hall, 1991.
• Ejercicios de Fundamentos de Informática: Tests y Ejercicios Resueltos. J.M. Rodríguez, J. Galindo,
M.J. Ferreiro y otros. Servicio de Publicaciones de la UCA, 1997.