Title: Cap
1Capítulo 6
2Estructuras
3Estructuras
- Recordemos que los arreglos son un conjunto de
datos de un mismo tipo. - Una estructura es un conjunto de datos que no son
necesariamente del mismo tipo. - No hay limitaciones en el tipo ni cantidad de
variables que pueda contener una estructura, la
única restricción es que una estructura no puede
contenerse a sí misma como miembro.
4Estructuras
5Ejemplo Estructuras
- typedef struct
- pfASDFace
-
- int level
- int tsid
- int vert3
- int attr3
- int refvert3
- int refattr3
- int child4
- int refvert3
- ushort gstateid
- ushort mask
- pfASDFace
6Aplicando estructura pfASDFace
7Idea
- Consideremos que deseamos mantener la información
de una persona. Estos datos podrían ser su
edad, su estatura, su peso, su nombre, sexo M o
F, etc. Una estructura nos permite agrupar en un
conjuntos a todos estos tipos de datos
8Partes de una estructura
9Arreglos y Estructuras
10Declaración
- Una estructura utiliza la palabra reservada
struct, un nombre identificador y entre llaves
sus campos con sus determinados tipos. - struct persona
-
- int edad
- float estatura, peso
- char nombre50
- char sexo
-
- struct persona gente1, gente2
11Otra Manera
- Podemos declarar la estructura y definir la
variables al mismo tiempo. - struct persona
-
- int edad
- float estatura, peso
- char nombre50
- char sexo
- gente1, gente2
12Inicialización
- Al igual que los arreglos las estructuras pueden
ser inicializadas al declararla. - struct persona
-
- int edad
- float estatura, peso
- char nombre50
- char sexo
- gente1 29, 1.89, 98, Francisco Bórquez",
M'
13Acceso a los elementos
- Para dirigirnos a un campo de una estructura
existe un operador que relaciona al nombre al
nombre de ella con un campo determinado, este
operador es el punto. - Su sintaxis es
- Nombre_estructura.nombre_campo
- Ejemplo
- gente1.edad30 gente1.peso80.5
14Ejemplo
15Ejemplo
- Desarrollar un programa que utilice la definición
del tipo alumno que se muestra abajo, permita
llenar los datos y calcular su promedio de notas,
e informar por pantalla si aprobó o no. - struct alumno
-
- char nombre 50
- char rut12
- int c1, c2, c3
- float prom
-
16Ejemplo
- void main ( )
-
- struct alumno alum_prg
- printf ( "ingrese nombre )
- scanf ( "s", alum_prg.nombre )
- printf ( "ingrese rut )
- scanf ( "s", alum_prg.rut )
- printf ( "ingrese los 3 certamenes )
- scanf ( "d d d", alum_prg.c1, alum_prg.c2,
alum_prg.c3 ) - alum_prg.prom ( alum_prg.c1 alum_prg.c2
alum_prg.c3 ) / 3 - if ( alum_prg.prom gt 55 )
- printf ( "aprobado )
- else
- printf ( "reprobado )
-
17Info dentro de estructuras
- Dentro de una estructura podemos tener no solo
datos simples, sino tipo de datos estructurados e
incluso otras estructuras. - struct coord
-
- int x, y
-
- struct datos
-
- float velocidad
- int eventos20
- struct coord posicion
-
18Ejemplo
- int main ( )
-
- struct datos movil
- int i
- movil.velocidad 1.45
- movil.posicion.x 3
- movil.posicion.y 7
- for ( i 0 i lt 20 i )
- movil.eventos i i
-
19Usos de Arreglo de Estructuras
- Tenemos la siguiente estructura
- struct vehiculo
-
- int num_serie
- char marca30
- int anio
- float costo
-
- Suponer, que estamos interesados en guardar la
información varios autos (unos 50). Ante esto
podríamos crear 50 variables y llenarlas con
información. Pero si analizamos, tenemos 50
variables que pueden conformar una colección de
datos de un mismo tipo, definición de ARREGLO - De esta manera se llega a un Arreglo de
Estructuras - struct vehiculo inventario50
20Arreglo de Estructuras
21Ejercicio
- Una librería desea almacenar sus productos en un
arreglo de registros. Cada registro debe incluir
los campos título, autor, ISBN (código), precio y
stock. Diseñe un programa C que permita realizar
las siguientes operaciones - - Ingresar una partida de 100 libros.
- - Encontrar un libro a partir de un código ISBN
ingresado por el usuario, mostrando el título,
autor, precio y stock correspondiente.
22Ejercicio
- Se requiere almacenar la información de un curso
de 10 alumnos a un arreglo de registros. A cada
alumno se le deben ingresar las 3 notas, y luego
calcular su promedio. - Se pide desarrollar un programa que permita el
ingreso de todos los datos del alumno, las 3
notas, y se le calcule promedio. Mostrar por
pantalla, nombre promedio, y además mostrar el
promedio del curso.
23Ejercicio
- struct alumno
-
- char nombre30
- char rol12
- int nota N
- float promedio
- curso A
24Utilizando typedef
- Sentencia para asignar un alias de tipo de dato,
puede dar un nuevo nombre a un tipo de dato ya
existente. Típicamente utilizada para darle un
nombre a tipos de datos no simples. - - enum
- - struct
- - arreglos
25Creando Nuevos Tipos
26Archivos
27Qué es un archivo?
- Un archivo es una estructura de datos de un
mismo tipo, sean éstos simples o estructurados. - Un archivo se almacena en un dispositivo
secundario (disco duro, cinta, CD-DVD, etc.), la
particularidad es que los datos contenidos en un
archivo después de ejecutar el programa no se
pierden.
28Usos
- La entrada y salida estándar de datos (teclado y
pantalla) pueden ser reemplazado por el uso de
archivos. - Los programas pueden utilizan archivos para
comunicarse con el otros programas, además es la
forma más simple de almacenar información (hacer
persistente los datos). Por ejemplo con el
objetivo de generar informes, documentos y/o
reportes.
29Leer-Gurdar información
30Tipos
- Tipo Texto
- Es una secuencia de caracteres.
- En un flujo de texto, pueden ocurrir ciertas
conversiones de caracteres si el entorno del
sistema lo requiere. - El número de bytes escritos y leídos puede no ser
iguales. - Tipo Binario
- Es una secuencia de bytes con una correspondencia
de uno a uno con los dispositivos externos. - No se realizan conversiones de caracteres.
- El número de bytes escritos y leídos es el mismo.
31Archivos para C
- La entrada y salida a archivos es un aspecto
dependiente del S.O. Las librerías de C proveen
un conjunto de funciones para trabajar con
archivos. - Se pueden distinguir dos tipos de funciones de
E/S, las tipos Unix-Linux que trabajan sin
buffer, y la estándar ANSI que utilizan buffer
intermedio (trabajaremos con el sistema ANSI).
32Sistema de archivos ANSI C
- La librería stdio.h nos provee un cojunto de
funciones - - fopen( ) abrir un archivo
- - fclose( ) cerrar un archivo
- - fputc ( ) escribe un char en archivo
- - fgetc ( ) lee un char de un archivo
- - fseek ( ) busqueda de byte
- - fprintf ( ) printf para archivos
- - fscanf ( ) scanf para archivos
- - feof ( ) indentificador de final de archivo
- - ferror ( ) devuelve 1 o 0 si hubo error en el
flujo - - rewind ( ) se posiciona al inicio del archivo
- - remove ( ) borra una archivo
33Stream-File
- Las operaciones de archivos se hacen a través de
un stream. Un stream es una serie ordenada de
byte (cadena de muchos bytes). - Leer o escribir un archivo implica leer o
escribir un stream. - Para asociar un stream con un archivo se crea un
puntero a una estructura FILE, la cual contiene
la información necesaria para interactuar con el
S.O.
34Sistema de Archivos
- La lógica para trabajar con archivo será
- - Para lectura abrir un archivo, leo la
información y luego se cierra el archivo - - Para escritura abrir (crear) archivo,
escribir la información y luego cerrar el
archivo. - La inicialización de un FILE, o dicho en otras
palabras, la apertura de un archivo se hace con
la función fopen(archivo, modo). El cierre se
hace con fclose(archivo).
35Abrir archivo
- Interfaz
- FILE fopen(const char nombre_archivo, const
char modo) - Donde
- - Nombre_archivo es el archivo con el cual se
trabajará (path incluido). - - Modo es el modo de acceso para el stream.
36Modos de Acceso
- El modo indica si el archivo se abrirá, o si se
creará, si es de texto o - binario. Los modo posibles para C son
- - r sólo lectura. El archivo debe existir.
- - w se abre para escritura, se crea un archivo
nuevo o se sobreescribe si ya existe. - - a añadir, se abre para escritura, el cursor
se sitúa al final del archivo. Si el archivo no
existe, se crea. - - r lectura y escritura. El archivo debe
existir. - - w lectura y escritura, se crea un archivo
nuevo o se sobreescribe si ya - existe.
- - a añadir, lectura y escritura, el cursor se
sitúa al final del archivo. Si el - archivo no existe, se crea.
- - t tipo texto, si no se especifica "t" ni
"b", se asume por defecto que es "t" - - b tipo binario.
37Ejemplo
- FILE a, b, c, d
- main ( )
-
- a fopen ( "datos.txt", "r )
- b fopen ( "nombres.dat", "a )
- c fopen ( "ipc.tex", "rt )
- d fopen ( "c\\cambios.rtf", "rb )
- ..........
-
38Error al abrir un archivo
- Abrir una archivo (lectura, agregar) que no
existe causa un error. Esta situación puede ser
fácilmente detectada de la siguiente forma - FILE arch
- If ( ! ( arch fopen ( nombre_archivo, modo ) )
) -
- printf ( "no es posible leer s",
nombre_archivo ) - return ( 1 )
-
- Sin no existe el archivo, la función fopen
devuelve NULL.
39Cerrar un Archivo
- No se debe olvidar cerrar todos los archivos
abiertos. Al cerrar los archivos, se guardan los
datos que aún están en el buffer y además
actualiza algunos datos de la cabecera del arch
que mantiene el S.O. - Además, libera el archivo para que otros
programas puedan abrirlo.
40Cerrando Archivos
- La función es fclose, y su prototipo es
- int fclose(FILE archivo)
- Devuelve cero si no hay error, y EOF en
- caso contrario.
- Ejemplo
- FILE arch
- arch fopen ( archivo.grande", "r )
- ......
- fclose ( arch )
41Trabajando sobre archivos
- Las operaciones de lectura o escritura que
podemos realizar sobre los archivos son
funciones de la librería stdio.h que pueden
trabajar en base a - - Caracteres (char)
- - Líneas
- - Bloques
42Funcion fgetc ( )
- Lectura de sólo un carácter desde un archivo, el
prototipo de esta función es - int fgetc ( FILE archivo )
- El valor de retorno es un carácter leído
- como un unsigned char convertido a int.
- Si al leer no hay un carácter disponible el
- valor de retorno es EOF.
43Función fputc ( )
- Escritura de sólo un carácter hacia un archivo.
- int fputc ( int carácter, FILE archivo )
- El valor de retorno es el carácter escrito, si la
operación de escritura fue realizada, de los
contrario devuelve EOF. - Los parámetros son el carácter convertido a int y
un puntero FILE al archivo.
44Funcion feof ( )
- Prototipo
- int feof ( FILE archivo )
- Función que se utiliza para comprobar si se ha
- llegado a fin de archivo (end of file).
- En los archivos guardas datos de un mismo tipo ya
- sean simple o estructuras, no tenemos información
- de cuantos registros hay, la idea será ir
realizando - lecturas consecutivas hasta que se llegue a final
de - archivo.
- El valor de retorno es 1 cuando se ha llegado a
fin - de archivo, de los contrario el retorno es 0.
45Función rewind ( )
- Prototipo
- void rewind ( FILE archivo )
- Función rebobinar, sitúa el cursor de
- lectura/escritura en el primer elemento del
archivo (la información que fue registrada
primero que todas).
46Ejemplo 1
- Realizar un programa en el cual guarde en un
archivo la información introducida por el usuario
a través del teclado. Se termina la introducción
por el teclado con el carácter . - Realizar un programa que lea lo
- introducido.
47Ejemplo 1
- include ltstdio.hgt
- int main ( )
-
- FILE archivo
- char c
- if ( ! ( archivo fopen ( "datos.dat", "w ) )
) -
- printf ( "No se puede abrir el archivo )
- return ( 1 )
-
do c getchar ( ) putc ( c, archivo
) while ( c ! ' ) rewind ( archivo
) while ( ! feof ( archivo ) ) c
fgetc ( archivo ) printf ( "c", c )
fclose ( archivo ) return ( 0 )
48Ejemplo 2
- // Muestra dos veces el archivo.
- include ltstdio.hgt
- int main ( )
-
- FILE arch
- arch fopen ( "ejemplo1.c", "r )
- while ( ! feof ( arch ) ) fputc ( fgetc ( arch
), stdout ) - rewind ( arch )
- while ( ! feof ( arch ) ) fputc ( fgetc ( arch
), stdout ) - fclose ( arch )
- getchar ( )
- return ( 0 )
-
49fprintf ( )
- Prototipo
- int fprintf ( FILE archivo, const char formato,
... ) - Impresión en archivo, funciona de manera
- similar que printf, pero no imprime la
- información por pantalla (stdout) sino que
- la salida es dirigida a un archivo.
- El retorno es el numero de caracteres
- enviados, si es negativo se produce un error
- en la salida.
50fscanf ( )
- Prototipo
- int fscanf ( FILE archivo, const char formato,
... ) - Ingreso de valores, funciona de manera
- similar a scanf, con la diferencia que los
- datos no son de teclado (stdin), sin que la
- entrada se toma desde un archivo.
- Retorna el número de datos asignado y EOF
- si ocurrió un error.
51Ejemplo
52Funcion fflush
- Prototipo
- int fflush ( FILE archivo )
- Esta función fuerza la salida de los datos
acumulados en el - buffer de salida del archivo. Para mejorar
el manejo de - archivos se utilizan buffers (almacenes
temporales de datos - en memoria) las operaciones de salida se hacen a
través del - buffer, y sólo cuando el buffer se
llena se realiza la - escritura en el disco y se vacía el buffer. En
ocasiones nos - hace falta vaciar ese buffer de un modo manual.
- El valor de retorno es 0 en caso de
éxito, y EOF en caso - contrario.
53Funcion fseek
- Prototipo
- int fseek ( FILE archivo, long int desp, int
origen ) - Función cuya utilidad es posicionar el cursor del
- archivo para leer o escribir en un lugar deseado
- Retorna 0 en caso de éxito.
- Parámetros el archivo, el desplazamiento desp
en - Bytes.
- El parámetro de origen (define 0, 1, 2)
- - SEEK_SET / comienzo de archivo /
- - SEEK_CUR / ubicación actual /
- - SEEK_END / fin de archivo /
54Funcion ftell
- Prototipo
- long int ftell ( FILE archivo )
- Función para averiguar cuál es la posición actual
del cursor de lectura/escritura de un archivo. - El retorno será la posición o -1 si se produjo un
error.
55Ejemplo
- include ltstdio.hgt
- int main ( int argc, char argv )
-
- FILE arch
- char cadena
- int i
- long lector
- arch fopen ( "archivo.txt", "r )
- for ( i 0 i lt 10 i )
-
- fgetc ( arch )
-
- printf ( "ld\n", ftell ( arch ) )
- printf ( "ld\n", SEEK_CUR )
fseek ( arch, 0L, SEEK_END ) printf (
"ld\n", ftell ( arch ) ) fseek (arch, 1L,
SEEK_SET ) printf ( "ld\n", ftell ( arch )
) printf ( "c\n", fgetc ( arch ) )
fclose ( arch ) return ( 0 )
56Funcion fgets
- fgets ( )
- Prototipo
- char fgets ( char cadena, int n , FILE
archivo ) - Función para lectura de string (cadena de
caracteres). - Lee n-1 caracteres o hasta que encuentra salto
de línea. - Cuando encuentra salto de línea, este también es
leído - Los parámetros son la cadena a leer, número
máximo - de caracteres a leer y el FILE.
- El valor de retorno es un puntero a la cadena
leída en - caso de lectura correcta, de lo contrario retorna
NULL - (ejemplo hacer una lectura y es fin de archivo.
57Funcion puts
- Prototipo
- int fputs ( const char cadena, FILE archivo
) - Función que escribe una cadena en un archivo. La
cadena es escrita sin el valor de retorno y sin
el carácter de finalización de string. - Parámetros cadena a escribir, archivo.
- El valor de retorno es un número positivo o EOF
en caso de error.
58Ejemplo
- include ltstdio.hgt
- int main ( )
-
- char nombre 10 "datos.dat", linea 81
- FILE arch
-
- arch fopen ( nombre, "r" )
- printf( "archivo s -gt ", nombre )
- if ( arch )
- printf ( "existe (ABIERTO)\n" )
- else printf ( "Error (NO ABIERTO)\n" )
- return ( 1 )
- printf ( "La primera linea del archivo
s\n\n", nombre ) - printf ( "s\n", fgets ( linea, 81, arch ) )
- if ( ! fclose ( arch ) )
- printf ( "\narchivo cerrado\n" )
- else
- printf ( "\nError archivo NO CERRADO\n" )
- return ( 1 )
59Ejemplo
- include ltstdio.hgt
- int main( )
- Ejemplo
- char nombre11"datos2.dat"
- FILE arch
- arch fopen( nombre, "w" )
- printf( "archivo s -gt ", nombre )
- if( arch )
- printf( "creado (ABIERTO)\n" )
- else printf( "Error (NO ABIERTO)\n" )
- return 1
- fputs( "Esto es un ejemplo usando \'fputs\'\n",
arch ) - if( !fclose(arch) )
- printf( "\narchivo cerrado\n" )
- else printf( "\nError arch NO CERRADO\n" )
- return 1
- return 0
60Guardando estructuras
- Al trabajar con estructuras o arreglos de
- estructuras, los más natural es guardar la
- información en un archivo, para que una
- vez terminado el programa la información
- no se pierda, y pueda ser recuperada
- nuevamente en cualquier momento.
- A continuación veremos algunas funciones para
trabajar con estructuras y archivos.
61Funcion fread
- Prototipo
- size_t fread ( void ptr,
- size_t tamaño,
- size_t nregistros,
- FILE archivo)
- Función capaz de leer desde un archivo uno o
varios registros de la misma longitud a partir de
una dirección de memoria determinada. - El valor de retorno es el número de registros
leídos. - Parámetros un puntero a la memoria donde se
almacenarán, el tamaño de cada registro, el
número de registros a leer y el archivo de donde
se lee.
62Funcion fwrite
- Prototipo
- size_t fwrite ( void ptr,
- size_t tamaño,
- size_t nregistros,
- FILE archivo )
- Función que permite escribir en un archivo uno o
varios registros de una misma longitud
almacenados a partir de una dirección de memoria
determinada. - El valor de retorno es el número de registros
escritos. - Parámetros una puntero a la memoria donde se
almacenarán los datos, el tamaño de cada
registro, el número de registros a escribir y el
archivo de donde se escribirán.
63Ejemplo
- include ltstdio.hgt
- struct computador
-
- char placa 20 ,
- procesador 20
- int memoria,
- velocidad,
- t_disco
- stock 4 "asus", "intel p4", 256,
2600, 2 , - "msi", "amd athlon", 512, 2800, 80 ,
- "microstar", "celeron", 2400, 60 ,
- "A-open", "Septron", 3000, 120 ,
- s
- FILE arch
64- int main ( int argc, char argv )
-
- arch fopen ( "computer.tex", "wb )
- fwrite ( stock, sizeof(stock0),3,arch)
- fwrite ( stock3, sizeof(stock3), 1, arch)
- rewind ( arch)
- printf ( "placa \t procesador \t memoria \t
velocidad \t disco duro \n") - while ( ! feof ( arch ) )
-
- fread ( s, sizeof ( s ), 1, arch )
- printf ( "s\t\ts\t\td\t\td\t\td\n",
- s.placa,
- s.procesador,
- s.memoria,
- s.velocidad,
- s.t_disco )
-
-
- fclose ( arch )
65Ejemplo
- include ltstdio.hgt
- struct computador
-
- char placa 20 ,
- procesador 20
- int memoria,
- velocidad,
- t_disco
- s
- FILE arch
int main ( int argc, char argv ) arch
fopen ( "computer.tex", "r ) while (
fread ( s, sizeof ( s ),1,arch) ! feof (
arch) ) printf ( "s\t\ts\t\td\t\td
\t\td\n", s.placa, s.procesador, s.memori
a, s.velocidad, s.t_disco ) fclose
( arch ) return ( 0 )
66FIN