ING. YIM ISAIAS APESTEGUI FLORENTINO

Anuncio
Estructuras
de Archivos
ING. YIM ISAIAS APESTEGUI FLORENTINO
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
1
Desbordamiento de búfer
En seguridad informática y programación, un
desbordamiento de buffer (del inglés buffer
overflow o buffer overrun) es un error de software
que se produce cuando se copia una cantidad de
datos sobre un área que no es lo suficientemente
grande para contenerlos, sobrescribiendo de esta
manera otras zonas de memoria. Esto se debe en
general a un fallo de programación. La
consecuencia de escribir en una zona de memoria
imprevista puede resultar impredecible.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
2
Existen zonas de memoria protegidas por el
sistema operativo. Si se produce la escritura
fuera de una zona de memoria protegida se
producirá una excepción del sistema de
acceso a memoria seguido de la terminación
del programa. Bajo ciertas condiciones, un
usuario obrando con malas intenciones
puede aprovecharse de este mal
funcionamiento o una vulnerabilidad para
tener control sobre el sistema.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
3
Si el programa que tiene el error en
cuestión tiene privilegios especiales se
convierte además en un fallo de
seguridad. El código copiado
especialmente preparado para obtener
los privilegios del programa atacado se
llama shellcode.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
4
Un desbordamiento de búffer ocurre cuando
los datos que se escriben en un búffer
corrompen aquellos datos en direcciones de
memoria adyacentes a los destinados para el
búffer, debido a una falta de validación de los
datos de entrada. Esto se da comúnmente al
copiar cadenas de caracteres de un búffer a
otro.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
5
Ejemplo básico
En este ejemplo, un programa tiene definidos dos
elementos de datos continuos en memoria: un buffer
de 8 bytes tipo string, A, y otro de dos bytes tipo
entero, B. Al comienzo, A contiene bytes nulos y B
contiene el número 3 (cada carácter se representa
mediante un byte).
0
0
0
0
0
0
Buffer A
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
0
0
0
3
Buffer B
6
A continuación, el programa intenta
almacenar la cadena de caracteres
"demasiado" en el buffer A, seguido de
bytes nulos para marcar el fin de string. Al
no validarse la longitud de la cadena, se
sobrescribe el valor de B:
'd'
'e'
'm'
'a'
's'
'i'
Buffer A
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
'a'
'd'
'o'
0
Buffer B
7
A pesar de que el programador no quería cambiar
el contenido del búffer B, el valor de éste ha sido
reemplazado por un número equivalente a parte
de la cadena de caracteres. Para este ejemplo, en
un sistema big-endian que use ASCII, el carácter
'o' seguido del byte nulo equivale al número
28416.
Si B fuese la única variable aparte de A definida en
el programa, la escritura de datos que sobrepasen
los límites de B generarían un error como
segmentation fault, concluyendo así el programa.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
8
RECORDANDO…
La función strcpy:
char *strcpy (char *cadena1, const char *cadena2);
//Prototipo de strcpy
Sirve para copiar la cadena cadena2 dentro
de cadena1. Devuelve el valor de cadena1. strcpy recibe dos parámetros:
un apuntador a char (modificable), y un apuntador a char constante. Y
devuelve un apuntador a char.
La funcion strncpy:
La función strncpy:
char *strncpy (char *cadena1, const char *cadena2, size_t n)
Sirve para copiar n caracteres de cadena2 hacia cadena1. Devuelve el
valor de cadena1.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
9
Código fuente de ejemplo
En el siguiente ejemplo se presenta un código fuente en C con un error de
programación. Una vez compilado, el programa generará un
desbordamiento de buffer si se lo invoca desde la línea de comandos con
un argumento lo suficientemente grande, pues este argumento se usa para
llenar un buffer, sin validar previamente su longitud
/* overflow.c - demuestra un desbordamiento de buffer */
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
char buffer[10];
if (argc < 2)
{ fprintf(stderr, "MODO DE USO: %s string\n", argv[0]);
return 1; }
strcpy(buffer, argv[1]);
return 0;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
10
Strings de 9 caracteres o menos no provocarán desbordamiento de buffer.
Por el contrario, strings de 10 caracteres o más sí: esto siempre es
incorrecto, aunque no siempre resultará en un error del programa o
segmentation fault.
/* mejor.c - demuestra un método de resolver el problema */
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{ char buffer[10];
if (argc < 2)
{ fprintf(stderr, "MODO DE USO: %s string\n", argv[0]);
return 1; }
strncpy(buffer, argv[1], sizeof(buffer));
buffer[sizeof(buffer) - 1] = '\0';
return 0;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
11
1. Problema:
En la vida real es necesario agrupar con frecuencia datos de
distintos tipos: por ejemplo, el documento nacional de identidad
contiene, entre otros, un entero (el número)
y cadenas de caracteres (el nombre, los apellidos, etc.);.
Solución:
Los registros permiten crear estructuras que pueden contener
entidades de distinto tipo, formando así, un árbol de estructuras y
subestructuras de datos.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
12
2. Definición de registro.
Un registro (record) es un tipo de datos estructurado
(denominado dato record) que consta de un conjunto de
elementos que pueden ser del mismo tipo o de tipos
diferentes.
Los componentes de un registro se denominan campos.
Cada campo tiene un nombre llamado identificador de
campo, que es algún identificador elegido por el
programador cuando se declara el tipo de registro y un
tipo que se especifica cuando se declara el tipo de dato
record.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
13
3. Registros en ANSI C.
La forma de definir registros en C es mediante el uso de estructuras. Una
estructura es una colección de uno o más tipo de elementos denominados
miembros, cada uno de los cuales puede ser de un tipo de dato diferente.
4. Declaración de estructuras.
Struct <nombre>
{
<tipo-1> <variable-1>;
<tipo-2> <nombre-2>;
…………………….
<tipo-n> <nombre-n>;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
14
5. Ejemplo de Declaración de una estructura.
Struct Musica_Cds
{
char titulo[16];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
};
Struct complejo
{
float parte_real, parte_imaginaria;
};
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
15
6. Definición de variables de Estructuras.
La declaración anterior, solo indica el nombre de un estructura y sus
campos componentes. Para asignar un área de memoria de tipo estructura,
es necesario definir una variable.
Para definir una variable, existen dos formas:
a) Listando los nombres de las variables a continuación de la estructura.
struct musica_cds
{
char titulo[16];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
} cd1 cd2, cd3;
b) Listando el nombre de la estructura seguida por los nombres de las
variables en cualquier lugar del programa.
struct musica_cds cd1,cd2,cd3; (En C++ no se requiere la palabra struct)
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
16
7. Asignación de estructuras.
Las variables estructuras se pueden asignar directamente entre ellas
produciéndose un movimiento de cada una de sus componentes.
La asignación directa de variables struct requiere que ambas variables
estén definidas bajo la misma estructura.
Ejemplos:
struct musica_cds
{
char titulo[16];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
} cd1 cd2, cd3;
cd1=c2;
cd1=cd2=cd3;
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
17
8. Inicialización de estructuras.
Las variables estructuras se pueden inicializar de dos formas: En cualquier
parte de la sección de código del programa o bien en la declaración o en la
definición de la estructura. El formato es el siguiente:
struct <nombre_variable> {valor-1,valor-2,….,valor-n};
El formato de inicialización anterior, asigna a los miembros de la estructura
cada uno de los valores separados por coma y entre llaves.
Debe existir una concordancia en tipo y cantidad de datos asignados.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
18
Ejemplo:
struct musica_cds
{
char titulo[50];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
} cd1={"Diamantes y Oxidos","Joan Baez", 18,25000,"20080701"}, cd2, cd3;
struct complejos {float real, imaginario; };
struct musica_cds x;
struct complejos z1= {41,25}, z2;
int main()
{
cd3= cd2= cd1;
printf("%s\n", cd1.titulo);
printf("%s\n", cd2.titulo);
printf("%s\n", cd3.titulo);
printf("%f %f\n", z1.real, z1.imaginario);
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
19
9. Acceso a estructuras.
9.1. Almacenamiento de información en estructuras.
Se puede almacenar información en una estructura mediante inicialización, asignación
o lectura. Formato para acceder a los campos:
<nombre_variable> . <nombre_miembro> = <valor>;
Ejemplo asignación:
struct musica_cds
{
char titulo[50];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
} cd1,cd2,cd3;
int main()
{
strcpy(cd1.titulo,"Diamantes y Oxidos");
strcpy(cd1.artista,"Joan Baez");
cd1.canciones=18;
cd1.precio=25000;
strcpy(cd1.fecha_compra,"20080701");
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
20
Ejemplo Letura:
struct musica_cds
{
char titulo[50];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
} cd1,cd2,cd3;
void main()
{
printf("Ingrese
printf("Ingrese
printf("Ingrese
printf("Ingrese
printf("Ingrese
titulo:"); scanf("%s",cd1.titulo);
artista:"); scanf("%s", cd1.artista);
canciones:"); scanf("%d", &cd1.canciones);
precio:"); scanf("%d", &cd1.precio);
fecha de compra:"); scanf("%s", cd1.fecha_compra);
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
21
9.2. Recuperación de información desde estructuras.
La información contenida en una estructura se recupera usando la asignación o bien imprimiendo
los miembros de una estructura. En ambos casos se debe usar el operador punto para referenciar
los miembros. Ejemplo:
struct musica_cds
{
char titulo[50];
char artista[30];
int canciones;
int precio;
char fecha_compra[8];
} cd1,cd2,cd3;
void main()
{
printf("Ingrese titulo:"); scanf("%s",cd1.titulo);
printf("Ingrese artista:"); scanf("%s", cd1.artista);
printf("Ingrese canciones:"); scanf("%d", &cd1.canciones);
printf("Ingrese precio:"); scanf("%d", &cd1.precio);
printf("Ingrese fecha de compra:"); scanf("%s", cd1.fecha_compra);
cd2=cd1; cd2.precio=cd2.precio+1000;
printf("Titulo:%s\n",cd2.titulo);
printf("Artista:%s\n",cd2.artista);
printf("Canciones:%d\n",cd2.canciones);
printf("Precio:%d\n",cd2.precio);
printf("Fecha Compra:%s\n",cd2.fecha_compra);
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
22
9.3. Estructuras como punteros.
Las estructuras es posible operarlas como punteros utilizando ya sea el operador de indirección o
bien el operador de puntero(->). Ejemplo:
#include <stdio.h>
#include <stdlib.h>
const n=10;
struct datos
{
char nombre[40];
int edad;
};
void main()
{
struct datos alumno1;
struct datos *alumno2;
alumno2=&alumno1;
strcpy((*alumno2).nombre,"Juan");
alumno1.edad=45;
printf("Nombre: %s\n",(*alumno2).nombre);
printf("Edad: %d\n",alumno2->edad);
strcpy(alumno2->nombre,"Pedro");
alumno2->edad=55;
printf("Nombre: %s\n",alumno2->nombre);
printf("Edad: %d\n",(*alumno2).edad);
system("PAUSE");
return 0;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
23
10 Anidamiento de estructuras.
Una estructura puede contener como miembro otras estructuras en forma anidada, para diferenciar
los campos se requiere el uso de múltiples operadores punto. Ejemplo:
struct dir
{ char calle[40]; int numero; char comuna[50];};
struct fecha
{
int dia, mes, ano;
};
struct registro_personal
{
char nombre[50];
struct dir direccion;
};
struct registro_empleado
{
struct registro_personal dpersonales ;
struct fecha fecha_contrato;
long sueldo;
} e1;
int main()
{
strcpy(e1.dpersonales.nombre,"Juan");
e1.dpersonales.direccion.numero=3342;
e1.fecha_contrato.dia=2;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
24
11 Arreglos de estructuras y estructuras de arreglos.
Es posible crear arreglos cuyos elementos son estructuras y a la vez una estructura puede contener ente sus
miembros arreglos de distinto tipo. El acceso a un elemento se hace usando la notación de arreglos (fila, columna,
etc.) y la notación punto.
Ejemplo:
const n=10;
struct registro_alumnos
{
char nombre[100];
int certamen[3];
};
void main()
{
struct registro_alumnos curso[n];
int i , j; float promedio;
for (i=0;i< n;i++)
{
printf("%d Ingrese nombre:",i); scanf("%s",curso[i].nombre);
for (j=0;j<3;j++)
{
printf("%d Ingrese certamen numero %d:",i,j); scanf("%d",&curso[i].certamen[j]);
}
}
for (i=0;i<n;i++)
{
promedio=0;
for (j=0;j<3;j++) promedio+=curso[i].certamen[j];
promedio/=3;
printf("Alumno %d, promedio:%f\n",i,promedio);
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
25
12 Creación de tipos: Operador Typedef.
El operador TypeDef permite crear un nombre sinónimo de un tipo de dato ya existente que facilita la creación de
variables. Ejemplo:
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
26
13 Arreglos de estructuras y estructuras de arreglos.
Es posible crear arreglos cuyos elementos son estructuras y a la vez una estructura puede contener ente sus
miembros arreglos de distinto tipo. El acceso a un elemento se hace usando la notación de arreglos (fila, columna,
etc.) y la notación punto.
Ejemplo:
const n=10;
struct registro_alumnos
{
char nombre[100];
int certamen[3];
};
void main()
{
struct registro_alumnos curso[n];
int i , j; float promedio;
for (i=0;i< n;i++)
{
printf("%d Ingrese nombre:",i); scanf("%s",curso[i].nombre);
for (j=0;j<3;j++)
{
printf("%d Ingrese certamen numero %d:",i,j); scanf("%d",&curso[i].certamen[j]);
}
}
for (i=0;i<n;i++)
{
promedio=0;
for (j=0;j<3;j++) promedio+=curso[i].certamen[j];
promedio/=3;
Organizacion de Archivos: Ing. Yim
printf("Alumno %d, promedio:%f\n",i,promedio);
Isaias Apestegui Florentino
}
27
14. Archivos.
Un archivo es una colección de datos que son almacenados de
manera estructurada, cuyas entidades poseen ciertos aspectos en
común y se encuentran organizados para algún propósito.
Carpetas:
Conjunto de carpetas
y archivos
Archivos
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
28
Características. Hasta el momento hemos trabajado con
estructuras de datos que se almacenan en memoria principal.
Cuando el programa termina, se pierden todos los datos. Los
archivos son estructuras que permiten almacenar
información en forma permanente en memoria secundaria
(disco duro, Pen-drive, etc.).
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
29
Usos de archivos.
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-reportes.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
30
Leer y Guardar información en archivos
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
31
Tipos de archivos:
Los archivos en ANSI C pueden contener información en formato
texto (ASCII) o bien en formato binario. Esto no crea dos tipos de
flujo de datos:
Flujos 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.
Flujos Binarios:
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.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
32
Descripción de archivos de texto.
La función booleana feof() devuelve el valor true(1) si se ha
alcanzado la marca de fin de archivo o false (0) en otro
caso.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
33
Descripción de archivos binarios.
La función booleana feof() devuelve el valor true(1) si se
ha alcanzado la marca de fin de archivo o falkse (0) en otro
caso.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
34
Sistema de Archivos en ANSI C.
La librería stdio.h nos provee un conjunto de funciones:
- fopen( ): abrir un archivo
- fclose( ): cerrar un archivo
- fputc ( ): escribe un char en archivo
- fgetc ( ): lee un char de un archivo
- fseek ( ): búsqueda 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 un
archivo
Organizacion
de Archivos: Ing. Yim
Isaias Apestegui Florentino
35
Operaciones básicas para el uso de archivos.
Antes de usar un archivo se debe declarar y abrir y una vez terminado uso se debe
cerrar:
Declaración:
Se declara con el tipo OPEN predefinido en la función stdio.h. El formato es:
FILE *<nombre lógico de archivo>;
Apertura:
<nombre lógico de archivo> = fopen("nombre", "modo");
Obs: “nombre”: Es el nombre físico del archivo.
Cerrar archivo
fclose(<nombre lógico de archivo>);
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
36
Definición de los modos de uso:
“Modo” es alguna de las siguientes:
r : sólo lectura (read)
w : escritura desde el comienzo del archivo (write)
a : escritura añadida al final del archivo (append)
a+ : Lectura y escritura añadida al final del archivo (append)
r+ : lectura y escritura
w+:escritura y lectura
rb :sólo lectura (archivo binario)
wb :escritura desde el comienzo del archivo (archivo binario)
ab :escritura añadida al final del archivo (archivo binario)
t: tipo texto, si no se especifica "t" ni "b", se asume por defecto que es "t"
b: tipo binario
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
37
Ejemplo:.
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", "r+b");
..........
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
38
Ejemplo:.
FILE *arch;
arch=fopen(“archivo.txt","r");
......
fclose(arch);
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
39
Operaciones sobre archivos
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
40
Función de detección de fin de archivo: feof().
Pemrite detectar cuando se ha llegado al fin de archivo y por lo tanto ya no es posible
seguir leyendo.
Fin de Archivo:
int feof(FILE *archivo);
Obs: El valor de retorno es 1 cuando se ha llegado a fin de archivo, de los contrario el retorno es 0.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
41
Función para saber donde está el cursor: ftell().
Permite saber donde se encuentra ubicado el cursor.
Ubicación del cursor:
long int ftell(FILE *archivo);
Obs:
-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
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
42
Formatos de lectura y escritura: Funciones fscan() y fprintf().
Permiten leer y escribir hacia y desde un archivo de texto.
Impresión:
int fprintf(FILE *fp, "cadena de control", tipo arg1, tipo arg2, ...);
Obs. El retorno es el número de caracteres impreso. Este es negativo si se produce un
error.
Lectura:
int fscanf(FILE *fp, "cadena de control", &arg1, &arg2, ...);
Obs: Los argumentos de fscanf() se deben pasar por referencia. Retorna el número de
caracteres leídos y EOF si hay errror.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
43
Ejemplo: Funciones fprintf() y fscanf().
#include <stdio.h>
#include <stdlib.h>
FILE *arch; FILE *inf;
int main()
{
int i,n1,n2,n3;
arch=fopen("notas.dat","w");
for (i=0;i<3;i++)
{
printf("\nnotas alumno:%d",i);
printf("Ingrese sus 3 notas:");
scanf("%d %d %d",&n1,&n2,&n3); fprintf(arch,"%d %d %d\r\n",n1,n2,n3);
}
fclose(arch); inf=fopen("notas.dat","r");
i=0;
while (!feof(inf))
{
fscanf(inf,"%d %d %d",&n1,&n2,&n3);
if ( !feof(inf) )
{
printf("\n%d %d %d",n1,n2,n3);
printf("Alumno %d promedio=%d",i,(n1+n2+n3)/3);
};
i++;
};
system("PAUSE");
return 0;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
44
Formatos de lectura y escritura: Funciones fgetc() y fputc().
Permiten hacer lectura/ escritura de un solo caracter:
Impresión:
int fputc(int carácter, FILE *archivo);
Obs. El valor de retorno es el carácter escrito, si la operación de escritura fue realizada, de los
contrario devuelve EOF
Lectura:
int fgetc(FILE *archivo);
Obs.
-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
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
45
Ejemplo: Funciones fgetc() y fputcf().
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *archivo;
char c; int i;
archivo=fopen("datos.dat","w");
for (i=0;i<3;i++)
fputc('A',archivo);
fclose(archivo);
archivo=fopen("datos.dat","r");
while(!feof(archivo) )
{
c=fgetc(archivo);
printf("%c",c);
}
fclose(archivo);
system("PAUSE");
return 0;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
46
Formatos de lectura y escritura: Funciones fgets() y fputs().
Permiten hacer lectura/ escritura de strings:
Impresión:
int fputs(const char *cadena, FILE *archivo);
Obs.
-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
Lectura:
char *fgets(char *cadena, int n ,FILE *archivo);
Obs:
- 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.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
47
Ejemplo: Funciones fgets() y fputs().
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int i; char str[20]; char str1[10];
FILE *s; FILE *e;
s=fopen("datos.txt","w");
for (i=0;i<5; i++)
{
itoa(i,str1,5);
strcpy(str,"string numero:");
strcat(str, str1);
fputs(str,s);
};
fclose(s); e=fopen("datos.txt","r");
while (!feof(e))
{
fgets(str,16,e);
if (!feof(e))
printf("%s\n",str);
}; fclose(e);
system("PAUSE"); return 0;
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
}
48
Formatos de lectura y escritura: Funciones fread() y fwrite().
Permiten hacer lectura/ escritura de datos binarios:
Impresión:
size_t fwrite(void *ptr, size_t tamaño, size_T nregistros, FILE *archivo);
Obs.
-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
Lectura:
size_t fread(void *ptr, size_t tamaño, size_t nregistros, FILE *archivo);
Obs:
-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
de Archivos:
Ing. Yim
número de registros a leer y el Organizacion
archivo de donde
se lee
49
Isaias Apestegui Florentino
Ejemplo: Funciones fread() y fwrite().
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
FILE *s;
FILE *e;
int i;
s=fopen("binario.dat","w");
for (i=1000;i<1005;i++)
fwrite(&i,sizeof(i),1,s);
fclose(s);
e=fopen("binario.dat","r");
while (!feof(e))
{
fread(&i,sizeof(i),1,e);
if (!feof(e))
printf("%d\n",i);
} fclose(e);
system("PAUSE");
return 0;
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
50
Función de reubicación del cursor de lectura: rewind().
Permite volver a iniciar la lectura de un archivo.
Reubicación de cursor:
void rewind(FILE *archivo);
Obs: 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).
.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
51
Ejemplo: Funciones rewind().
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *a;
struct alumno { char nombre[50]; int nota; };
struct alumno curso[3]; struct alumno registro;
strcpy(curso[0].nombre,"Juan Vergara"); curso[0].nota=99;
strcpy(curso[1].nombre,"Victor Chavez"); curso[1].nota=55;
strcpy(curso[2].nombre,"Oscar Marin"); curso[2].nota=33;
a=fopen("vector.dat","w+");
fwrite(&curso,sizeof(curso[0]),1,a);
fwrite(&curso[1],sizeof(curso[1]),2,a);
rewind(a);
while (!feof(a))
{
fread(&registro,sizeof(registro),1,a) ;
if (!feof(a))
{
printf("%s ",registro.nombre);
printf("%i\n",registro.nota);
};
}; fclose(a); system("PAUSE"); return
0;
Organizacion
de Archivos: Ing. Yim
Isaias
Apestegui
Florentino
}
52
Función de posicionamiento del cursor: fseek().
Permite volver a iniciar la lectura de un archivo.
Reubicación de cursor:
int fseek(FILE *archivo, long int desp, int origen);
Obs:
-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 en bytes
-El parámetro origen puede ser uno de los siguientes(define 0, 1, 2)
- SEEK_SET: comienzo de archivo
- SEEK_CUR: ubicación actual
- SEEK_END: fin de archivo
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
53
Ejemplo.
int main(int argc, char *argv[])
{
FILE *salida;
FILE *entrada;
char letra;
int i;
salida=fopen("archivo.txt","w");
fprintf(salida,"%s","123456789");
fclose(salida);
entrada=fopen("archivo.txt","r");
printf("posicion despues de abrir:%ld\n",ftell(entrada));
for (i=0; i<5; i++ ){
fgetc(entrada);
}
printf("posicion despues de leer 5 caracteres: %ld\n",ftell(entrada));
fseek(entrada, 0,SEEK_END);
printf("posicionarse al final: %ld\n",ftell(entrada));
fseek(entrada, 0,SEEK_SET);
printf("POsicionarse al inicio: %ld\n",ftell(entrada));
fseek(entrada, 1,SEEK_SET);
printf("POsicionarse 1 depues del inicio: %ld\n",ftell(entrada));
fseek(entrada, -1,SEEK_END);
printf("posicionarse 1 antes del final: %ld\n",ftell(entrada));
fseek(entrada, -2,SEEK_CUR);
printf("posicionarse 2 antes del actual: %ld\n",ftell(entrada));
}
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
54
Función para limpiar el buffer de lectura: fflush().
Permite posicionar el curso en una localización determinada por el numero de bytes.
Limpieza del buffer:
int fflush(FILE *archivo);
Obs:
-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
.
Organizacion de Archivos: Ing. Yim
Isaias Apestegui Florentino
55
Descargar