1. http://www.eps.uam.es/~phaya
PROG-I
2009-10
MACROS Y TIPOS DE
DATOS AVANZADOS
Tema 4 – 4.3 y 4.4
fuente: Proyecto Gutenberg (http://www.gutenberg.org/etext/2000) visualizado con hexdump
00000000 45 6e 20 75 6e 20 6c 75 67 61 72 20 64 65 20 6c |En un lugar de l|
00000010 61 20 4d 61 6e 63 68 61 2c 20 64 65 20 63 75 79 |a Mancha, de cuy|
00000020 6f 20 6e 6f 6d 62 72 65 20 6e 6f 20 71 75 69 65 |o nombre no quie|
00000030 72 6f 20 61 63 6f 72 64 61 72 6d 65 2c 20 6e 6f |ro acordarme, no|
00000040 20 68 61 20 6d 75 63 68 6f 0a 74 69 65 6d 70 6f | ha mucho.tiempo|
00000050 20 71 75 65 20 76 69 76 c3 ad 61 20 75 6e 20 68 | que vivía un h|
00000060 69 64 61 6c 67 6f 20 64 65 20 6c 6f 73 20 64 65 |idalgo de los de|
00000070 20 6c 61 6e 7a 61 20 65 6e 20 61 73 74 69 6c 6c | lanza en astill|
00000080 65 72 6f 2c 20 61 64 61 72 67 61 20 61 6e 74 69 |ero, adarga anti|
00000090 67 75 61 2c 0a 72 6f 63 c3 ad 6e 20 66 6c 61 63 |gua,.rocín flac|
000000a0 6f 20 79 20 67 61 6c 67 6f 20 63 6f 72 72 65 64 |o y galgo corred|
000000b0 6f 72 2e 20 55 6e 61 20 6f 6c 6c 61 20 64 65 20 |or. Una olla de |
000000c0 61 6c 67 6f 20 6d c3 a1 73 20 76 61 63 61 20 71 |algo más vaca q|
000000d0 75 65 20 63 61 72 6e 65 72 6f 2c 0a 73 61 6c 70 |ue carnero,.salp|
000000e0 69 63 c3 b3 6e 20 6c 61 73 20 6d c3 a1 73 20 6e |icón las más n|
000000f0 6f 63 68 65 73 2c 20 64 75 65 6c 6f 73 20 79 20 |oches, duelos y |
00000100 71 75 65 62 72 61 6e 74 6f 73 20 6c 6f 73 20 73 |quebrantos los s|
00000110 c3 a1 62 61 64 6f 73 2c 20 6c 61 6e 74 65 6a 61 |ábados, lanteja|
00000120 73 20 6c 6f 73 0a 76 69 65 72 6e 65 73 2c 20 61 |s los.viernes, a|
00000130 6c 67 c3 ba 6e 20 70 61 6c 6f 6d 69 6e 6f 20 64 |lgún palomino d|
00000140 65 20 61 c3 b1 61 64 69 64 75 72 61 20 6c 6f 73 |e añadidura los|
00000150 20 64 6f 6d 69 6e 67 6f 73 2c 20 63 6f 6e 73 75 | domingos, consu|
00000160 6d c3 ad 61 6e 20 6c 61 73 20 74 72 65 73 0a 70 |mían las tres.p|
2. PROG-I /24PROG-I
Objetivos
Semana 6
4.1 Definir macros y tipos de datos en C
4.2 Hacer uso de arrays y estructuras
Semana 7
4.3 Tipos de datos definidos por el programador
4.4 Ficheros
Semana 8 y 9
4.5 Punteros y gestión dinámica de memoria
Curso 2009-10Tema 4 - Macros y tipos de datos 2
3. PROG-I /24PROG-I
Tipos de datos definidos por el programador
typedef tipo_dato nuevo_tipo_dato
typedef char mayusculas
typedef double escalar
typedef unsigned long size_t
typedef unsigned int metros, millas;
typedef escalar vector[N];
typedef escalar matriz[N][N];
typedef struct fecha { int dia, mes, anio;} Fecha;
typedef enum {FALSO, VERDADERO} boolean;
Curso 2009-10Tema 4 - Macros y tipos de datos 3
mayusculas c;
escalar f;
size_t tamano;
metros ancho, alto;
vector v;
matriz m;
Fecha fecha;
boolean encontrado;
4. PROG-I /24PROG-I
Ficheros
Almacenamiento de información externo a la memoria
principal. Habitualmente persistente (archivo en el disco
duro).
Tipo de datos almacenados
Archivos binarios
Datos homogéneos (simple o estructurados)
Secuencia de bytes
Archivos texto
Tipo de procesamiento
Procesamiento aleatorio o secuencial.
Operativa habitual
1. Abrir
2. Operar (leer y/o escribir)
3. Cerrar
Curso 2009-10 4Tema 4 - Macros y tipos de datos
5. PROG-I /24PROG-I
Ficheros
Ejemplos con hexdump
Fichero de texto: hexdump ej_fichero.txt
45 73 74 6f 20 65 73 20 75 6e 20 66 69 63 68 65 |Esto es un fiche|
72 6f 0a 64 65 20 74 65 78 74 6f |ro.de texto|
Fichero binario: hexdump ej_c.o
bc 0e f0 fe ff ff 8d b4 03 f0 fe ff ff fc b9 44 |?.????.?.??????D|
00 00 00 f3 a5 66 3b 55 f6 7c c5 8b 5d e0 8b 75 |...?f;U?|?.]?.u|
e4 8b 7d e8 c9 c3 66 0f 1f 44 00 00 55 89 e5 81 |?.}???f..D..U.?.|
ec 48 01 00 00 89 9d c8 fe ff ff 89 b5 cc fe ff |?H.....????.????|
ff 89 bd d0 fe ff ff e8 60 ff ff ff 89 9d e0 fe |?.??????`???..??|
ff ff 89 45 fc 89 55 f8 8b 75 fc 8d bd e4 fe ff |??.E?.U?.u?.????|
Curso 2009-10 5Tema 4 - Macros y tipos de datos
6. PROG-I /24PROG-I
Manejo de ficheros
Abrir: permite comenzar a operar con un fichero. Hay que proveer
Ruta donde se encuentra en fichero (localización + nombre)
Modos de operación: lectura, escritura, agregación
fopen: Abre un fichero para poder trabajar sobre él. Devuelve NULL
en caso de error.
FILE * fopen(const char * path, const char * mode);
Ej:
FILE * fp;
fp = fopen("prueba.txt","r");
if(fp== NULL) {
printf("Prueba.txt: No se puede abrir el ficheron"); //puts
return -1;
}
ó
if((fp = fopen("prueba.txt","r")) == NULL) {
printf("Prueba.txt: No se puede abrir el ficheron"); //puts
return -1;
}
Curso 2009-10 6Tema 4 - Macros y tipos de datos
7. PROG-I /24PROG-I
Modos de apertura
Mod
o
Operació
n
Le
er
Escri
bir
Cre
ar
Borra
r
r Lectura Si No No No
r+ Lectura/Es
critura
Si Si No No
w Escritura No Si Si Si
w+ Lectura/Es
critura
Si Si Si Si
a Escritura No Si Si No
a+ Lectura/Es
critura
Si Si No No
+ : el fichero se abra tanto para lectura como para escritura
Crear: Si no existe se crea un nuevo fichero.
Borrar: Si existe se trunca la longitud a cero.
Se puede añadir un tercer modificador b que indica que el fichero se abra
en modo binario. Ej. w+b
Curso 2009-10 7Tema 4 - Macros y tipos de datos
8. PROG-I /24PROG-I
Manejo de ficheros
Cerrar: indica que no se va a utilizar más el fichero. Si no
se llama el fichero puede quedar corrupto o incompleto.
fclose: cierra un fichero una vez que se haya terminado.
Devuelve 0 si ha cerrado correctamente
int fclose(FILE *fp);
Ej:
fclose(f);
Siempre hay que llamarla cuando se termine de emplear un
fichero.
Curso 2009-10Tema 4 - Macros y tipos de datos 8
10. PROG-I /24PROG-I
Lectura de un ficheros de texto
Lectura: lee un carácter (byte) o una línea de un fichero
fgetc, getc: lee el siguiente carácter dado un fichero fp abierto.
Tanto si se encuentre el final del fichero como si se produce un error
en la lectura se devuelve EOF.
int fgetc(FILE *fp);
fgets: lee al menos n-1 caracteres del fichero fp y los almacena en
la cadena de caracteres line. Si se detecta un salto de línea, el final
de fichero ó se produce un error se termina la lectura. Se devuelve
la cadena de caracteres, o NULL si se llego al final de fichero o se
produjo un error.
char * fgets(char * line, int n, FILE *fp);
Se añade el retorno de carro al final de la cadena de caracteres y el
carácter nulo (0) para indicar el fin de cadena.
Curso 2009-10 10Tema 4 - Macros y tipos de datos
11. PROG-I /24PROG-I
Ejemplo
Contar el número de caracteres de un fichero
Curso 2009-10Tema 4 - Macros y tipos de datos 11
#include <stdio.h>
int main(void)
{
FILE *fp;
int n = 0, c;
if ((fp = fopen("prueba.c","r")) == NULL)
return 1;
while ((c = fgetc(fp)) != EOF) n++;
fclose(fp);
printf("t%dn", n);
return 0;
}
12. PROG-I /24PROG-I
Escritura en un fichero
Escritura: escribe un dato en el fichero
fputc, putc: escribe un carácter en el fichero fp
(previamente abierto). Si se produce un error en la lectura
se devuelve EOF.
int fputc(int c, FILE *fp);
fputs: copia la cadena de caracteres en el fichero fp
(previamente abierto). Si se produce un error devuelve
EOF
int fputs(const char *s, FILE *fp)
Curso 2009-10Tema 4 - Macros y tipos de datos 12
13. PROG-I /24PROG-I
Ejemplo:
Curso 2009-10Tema 4 - Macros y tipos de datos 13
/*Recibe un fichero con correos-e, uno por linea, y devuelve
otro fichero con los correos validos */
#include <string.h>
#define MAX_TAM 255
int main(void)
{
FILE *fp1, *fp2;
char m[MAX_TAM+1];
fp1 = fopen("sucios.txt", "r");
fp2 = fopen("limpios.txt","w");
while (fgets(m, MAX_TAM, fp1) != NULL)
{
int i = 0;
while (i < strlen(m) && m[i] != '@') i++;
if (i < strlen(m))
fputs(m, fp2);
}
fclose(fp1);
fclose(fp2);
return 0;
}
¿Qué pasa si un correo-e tiene
un tamaño superior a MAX_TAM?
14. PROG-I /24
Control de errores
Curso 2009-10Tema 4 - Macros y tipos de datos 14
Errores: después de realizar una operación se puede cuando
ocurre algún error.
El código devuelto por las funciones no distingue entre fin de
fichero y error.
ferror: comprueba si ha habido algún error durante la operación.
Devuelve distinto de cero si lo ha habido
int ferror(FILE * stream);
if (ferror(fp))
{
fprintf(stderr, "%s: error escribiendo en %sn", prog, nombre);
exit(2);
}
feof: comprueba si se ha alcanzado el final de fichero. Devuelve
distinto de cero si lo ha habido
int feof(FILE * stream);
while (!feof(fp)) {
…
}
15. PROG-I /24
Entrada y salida estándar, y salida error
stdin: constante que representa la entrada estándar (con buffer)
FILE *fp = stdin;
stdout: constante que representa la salida estándar (con buffer)
stderr: constante que representa la salida error (sin buffer)
fprintf(stderr, "ERROR:%s", error);
Funciones de entrada y salida que actúan sobre la entrada/salida
estándar
getchar() eq. getc(stdin)
gets(s): función que nunca hay que utilizar.
putchar() eq. putc(c, stdout)
Curso 2009-10 15Tema 4 - Macros y tipos de datos
17. PROG-I /24PROG-I
Operaciones ficheros binarios
Permiten manejar más fácilmente ficheros que contienen
colecciones de datos de un mismo tipo.
¿Cómo se almacenaría la siguientes declaraciones en un
archivo de texto?
En un fichero binario:
0 1 2 3 4 5 N-1
reg1 reg2 reg3 reg4 reg5 reg6 regN eof
typedef struct {
float x,y,z ;
}Punto;
Punto puntos[MAX_PUNTOS];
Curso 2009-10 17Tema 4 - Macros y tipos de datos
18. PROG-I /24PROG-I
Lectura y escritura
fread: lee n * el_tam bytes del fichero fp y los guarda en el
array a. Devuelve el número de elementos leidos.
size_t fread(void *a, size_t el_tam, size_t n,
FILE *fp);
fread(puntos, sizeof(Punto), MAX_PUNTOS, fp);
fwrite: lee (n * el_tam) bytes del array a, y los escribe en
el fichero fp. Devuelve el número de elementos escritos.
size_t fwrite(const void *a, size_t el_tam, size_t
n, FILE *fp);
fwrite(puntos, sizeof(Punto), MAX_PUNTOS, fp);
Curso 2009-10 18Tema 4 - Macros y tipos de datos
19. PROG-I /24PROG-I
Ejemplo escritura
#include <stdio.h>
#define MAX_PUNTOS 2
…
int main(void)
{
FILE *fp;
long pos;
Punto r[MAX_PUNTOS]={{1.0, 1.5, -0.9},{2, 2.5, 3.4}};
fp = fopen("puntos.dat","wb");
if (!fp)
return 1;
fwrite(r, sizeof(Punto), MAX_PUNTOS, fp);
fclose(fp);
return 0;
}
Curso 2009-10Tema 4 - Macros y tipos de datos 19
20. PROG-I /24PROG-I
Ejemplo lectura (I)
int main(void)
{
FILE *fp;
int i;
Punto r[MAX_PUNTOS];
fp = fopen("puntos.dat","rb");
if (!fp)
exit(0);
fread(r, sizeof(Punto), MAX_PUNTOS, fp);
fclose(fp);
for (i=0; i < 2; i++)
printf("%.2f %.2f %.2fn", r[i].x, r[i].y, r[i].z);
return 0;
}
Curso 2009-10Tema 4 - Macros y tipos de datos 20
21. PROG-I /24PROG-I
Ejemplo lectura (II)
int main(void)
{
FILE *fp;
Punto r; /* un solo registro */
fp = fopen("puntos.dat","rb");
if (!fp)
return 1;
while(!feof(fp)) {
if (fread(&r, sizeof(Punto), 1, fp) != 0)
printf("%.2f %.2f %.2fn", r.x, r.y, r.z);
}
fclose(fp);
return 0;
}
Curso 2009-10Tema 4 - Macros y tipos de datos 21
22. PROG-I /24PROG-I
Operaciones ficheros binarios
Operaciones
fseek: sitúa el cursor en un posición específica (offset) a partir de
otra posición dada (place). SEEK_SET (comienzo), SEEK_CUR
(posición actual), o SEEK_END (Fin de fichero)
int fseek(FILE *fp, long offset, int place);
Ej: fseek(fp, i * sizeof(Punto), SEEK_SET);
rewind: establece la posición del fichero al principio del mismo.
void rewind(FILE *fp);
(void) fseek(fp, 0, SEEK_SET);
Ej: rewind(fp);
ftell: devuelve la posición actual del cursor del fichero.
long ftell (FILE * fp);
Ej: pos = ftell(fp);
Curso 2009-10 22Tema 4 - Macros y tipos de datos
23. PROG-I /24PROG-I
Ejemplos:
Punto r[MAX_PUNTOS];
/* obtener el tamaño de un fichero */
fseek (fp , 0 , SEEK_END);
tam = ftell (fp); /* tamaño en bytes */
/* Leer el primer registro */
rewind(fp);
fread(&r[0], sizeof(Punto), 1, fp);
/* Leer el último registro */
fseek (fp , 0 , SEEK_END);
fseek (fp , -1 * sizeof(Punto), SEEK_CUR);
fwrite(&r[MAX_PUNTOS-1], sizeof(Punto), 1, fp);
Curso 2009-10Tema 4 - Macros y tipos de datos 23
24. PROG-I /24PROG-I
Otras operaciones
fflush: vacía el buffer
int fflush(FILE *fp);
tmpfile: Abre un fichero temporal en modo "wb+" que
el sistema se encarga de borrar cuando se cierra, o se
termina el programa. Devuelve NULL si no es posible
FILE *tmpfile(void);
tmpname: crea un nombre para un archivo único
char * tmpnam(char * s);
NO ANSI C
rename: Cambia el nombre de un archivo por otro.. El
archivo tiene que estar cerrado.
int rename(const char *origen, const char * destino);
remove: Borra un archivo.
int remove(const char *nombre);
Curso 2009-10 24Tema 4 - Macros y tipos de datos