Coruniversitaria, Corporación Universitaria de Ibagué
Facultad de Ingeniería de Sistemas

Estructuras de Datos II 

Inicio

Generalidades

Ejercicios

Talleres

Proyecto

Ejercicios "amistosos"

 Archivos

  El almacenamiento de datos en variables simples y arreglos es temporal (memoria primaria). Los archivos son estructuras constituídas por colecciones de datos que se pueden guardar (grabar) para uso posterior mediante la ejecución de programas adecuados. Es decir, los archivos se utilizan para la retención permanente de información. Las computadoras guardan a los archivos en dispositivos de almacenamiento secundario, tales como discos magnéticos, discos ópticos y cintas. 
Existen dos modalidades para acceder a un archivo de datos: acceso secuencial y acceso directo o aleatorio. El acceso secuencial exige el tratamiento elemento a elemento; es necesaria una exploración secuencial comenzando desde el primer elemento. El acceso directo permite procesar o acceder a un elemento determinado referenciado directamente por su posición en el soporte de almacenamiento.

Un archivo de texto es un tipo estándar y está constituído por elementos que son caracteres pertenecientes al código ASCII.

Los archivos binarios están estructurados en elementos o registros. Los valores binarios almacenados en memoria se copian directamente en el disco. A los elementos de estos archivos se accede directamente, al no situarse éstos en posiciones físicamente consecutivas, sino en posiciones lógicas. Un puntero del archivo memoriza el rango o posición del registro para la próxima operación de lectura o escritura.
Un registro es la unidad mínima de transferencia de información entre un archivo y un programa. 
Un archivo de acceso aleatorio no es visualizable directamente en pantalla. Esto significa que los archivos binarios no pueden crearse -al igual que los de texto- con un editor del sistema operativo. En su lugar, un archivo binario se debe crear por la ejecución de un programa.

La mayoría de aplicaciones con archivos requieren que se altere el archivo cuando se procesa. Por ejemplo, en el procesamiento de registros de clientes, se puede desear añadir nuevos registros al archivo, modificar, borrar, o reordenar los registros. Estos requisitos sugieren varias estrategias computacionales.

Cuando se trata de actualizar los registros dentro de un archivo de datos, un enfoque para éste problema es trabajar con dos archivos: un archivo antiguo (la fuente) y otro nuevo. Se lee cada registro del archivo antiguo, se actualiza y se escribe en el nuevo archivo. Cuando se han actualizado todos los registros, se borra el archivo antiguo <system("del archi.dat")> o se almacena como copia de seguridad y se renombra el archivo nuevo <system("ren A.dat B.dat")>. Así, el archivo nuevo se convierte en la fuente para el siguiente turno de modificaciones.

Históricamente, el origen de éste método proviene de los primeros días de la computación, cuando los archivos de datos se almacenaban en cintas magnéticas. Sin embargo, éste método se usa todavía, ya que proporciona una serie de archivos fuente antiguos que pueden usarse para generar la historia de un cliente. El archivo fuente más reciente se puede utilizar también para crear de nuevo el archivo actual si éste se daña o se destruye.

Es muy importante familiarizarse con el procesamiento de archivos y entenderlo como un acercamiento al manejo de tablas en el actual diseño de bases de datos.

------------------------------------------------------------------------------------

 // Programa ejemplo para crear un archivo de acceso secuencial. Como ejercicio amistoso de programación, el alumno deberá codificar un ciclo indeterminado dentro de la  función adicionar_emp(),  e implementar las funciones modificar() y borrar() un registro  del archivo.

#include "iostream.h"
#include "conio.h"
#include "stdio.h"
#include "dos.h"
#define lp clrscr();
#define g gotoxy

struct empleado{ // estructura tipo registro de empleado
int codigo;
char nombre[50];
float sueldo;
};
empleado registro,aux;
int pos, codiaux, opc, t=sizeof(empleado); // tamaño del registro
char bandera; long filepos;
FILE *fp; // puntero al archivo

void mimarco(int t,int l,int b,int r,int f){
int col=l;
if (f==1){
gotoxy(l,t);printf("É");gotoxy(r,t);printf("»");
gotoxy(l,b);printf("È");gotoxy(r,b);printf("¼");
for (++l;l<r;++l){
gotoxy(l,t);printf("Í");gotoxy(l,b);printf("Í");
}
for (++t;t<b;++t){
gotoxy(col,t);printf("º");gotoxy(r,t);printf("º");
}
}else{
if (f==2){
gotoxy(l,t);printf("Ú");gotoxy(r,t);printf("¿");
gotoxy(l,b);printf("À");gotoxy(r,b);printf("Ù");
for (++l;l<r;++l){
gotoxy(l,t);printf("Ä");gotoxy(l,b);printf("Ä");
}
for (++t;t<b;++t){
gotoxy(col,t);printf("³");gotoxy(r,t);printf("³");
}
}else{
if (f==3){
++r;
for (l;l<r;++l){
gotoxy(l,t);printf("Í");
}
}else{
if (f==4){
++r;
for (l;l<r;++l){
gotoxy(l,t);printf("Ä");
}}}}}
}

void titulos(){
mimarco(1,1,24,80,1);
g(15,8); cout <<"CODIGO EMPLEADO :";
g(15,9); cout <<"NOMBRE :";
g(15,10); cout <<"SUELDO $";
}

void buscar(int codg){ //función búsqueda con paso de parámetro
bandera = 'f'; //falso
fseek(fp,0l,0); //ubicándose en el comienzo del archivo
//rewind(fp);
while((!feof(fp))&&(bandera=='f'))
{
//filepos=ftell(fp); //ftell retorna la posición actual dentro del archivo
fread(&registro,t,1,fp); //fread lee el archivo de t bytes
if(registro.codigo==codg)
{
bandera='t'; //verdadero
}
}
}

void adicionar_emp(){
bandera = 'f';
codiaux=0;
//fopen abre un archivo. En este caso "Empleado.dat" y
// asigna su dirección al puntero fp
fp=fopen("Empleado.dat","rb");
if(fp==NULL)
{
g(24,22);cout<< " <<CREANDO ARCHIVO...>> ";
fp=fopen("Empleado.dat","wb"); //si no existe, lo crea.
fclose(fp);
}
fp=fopen("Empleado.dat","rb+");
lp
g(15,6);cout <<"INGRESO DEL EMPLEADO";
titulos(); //Llama la función titulos()
g(35,8); cin>>codiaux;
buscar(codiaux); //Llama la función BUSCAR con el código
if (bandera =='t')
{
g(20,20); cout <<"ERROR!!!, Codigo de Empleado YA EXISTE!";
getche();
fclose(fp);
}
else
{
registro.codigo = codiaux;
g(35,9);
gets(registro.nombre);
g(35,10);
cin>>registro.sueldo;
fwrite(&registro,t,1,fp); //escribe un registro en el archivo
fclose(fp); //cierra el archivo
}
}

void consultar_emp(){
char op;
do{
lp
mimarco(1,1,24,80,1);
g(15,5); cout <<"CONSULTA POR CODIGO";
g(15,10); cout <<"CODIGO del Empleado a consultar -> ";
cin >> codiaux;
fp=fopen("Empleado.dat","rb");
if(fp==NULL){
g(25,20); cout <<"<<ERROR en apertura del Archivo>>";}
else
{
buscar(codiaux);
lp
//fseek(fp,(codiaux-1)*t,SEEK_SET);
//fread(&registro,t,1,fp);
if(bandera=='t'){
lp
titulos(); g(35,8);
cout<<registro.codigo; g(35,9);
cout<<registro.nombre; g(35,10);
cout<<registro.sueldo;
}
else{
g(20,20); cout <<"Codigo de Empleado NO EXISTE!!";}
}
g(15,12);cout<<"Desea consultar mas empleados? <s/n>... ";
cin >> op;
}while(op!='n'&&op!='N');
fclose(fp);
}

void listar_emp(){
fp=fopen("Empleado.dat","rb");
if(fp==NULL)
{
g(25,20); cout <<"<<ERROR en apertura del Archivo...";
getche();
}
else
{
rewind(fp);
while(!feof(fp))
{
fread(&registro,t,1,fp);
if (!feof(fp)){
lp
titulos(); g(35,8);
cout<<registro.codigo; g(35,9);
cout<<registro.nombre; g(35,10);
cout<<registro.sueldo; g(35,11);
getche();}
}
}fclose(fp);
}

int fecha(){
struct date d;
getdate(&d);
gotoxy(20,23);printf("%2d/%02d/%02d", d.da_year, d.da_day, d.da_mon);
return 0;
}
int hora(){
struct time t;
while(!kbhit()){
gettime(&t);
gotoxy(59,23);printf("%2d:%02d:%02d",t.ti_hour, t.ti_min, t.ti_sec);
}return 0;
}

menu(){
int c;
textbackground(BLUE);textcolor(WHITE);
lp;
mimarco(1,1,24,80,1);
textcolor(LIGHTBLUE);textbackground(BLACK);
gotoxy(34,1); cprintf("Pengin Soft");
gotoxy (21, 5); cout <<" U N I V E R S I D A D DE I B A G U E";
gotoxy (31, 6); cout <<"<CORUNIVERSITARIA>";
gotoxy (31, 8); cout <<"ARCHIVO DE EMPLEADOS";
mimarco(10,32,16,49,2);
gotoxy (34,11); cout <<"[1] Adicionar";
gotoxy (34,12); cout <<"[2] Consultar";
gotoxy (34,13); cout <<"[3] Listar";
gotoxy (34,14); cout <<"[4] Modificar";
gotoxy (34,15); cout <<"[5] Borrar";
gotoxy (29,17); cout <<"Escoja su opcion... [ ]";
gotoxy (24,19); cout <<"Para terminar, pulse la tecla [ESC]";
textcolor(LIGHTBLUE);textbackground(BLACK);
gotoxy(41,24); cprintf("GMV");
fecha(); hora();
gotoxy(51,17);c=getch();
return c;
}

void main(){
int c;
c=menu();
while (c != 27){
switch(c){
case '1': adicionar_emp();break;
case '2': consultar_emp();break;
case '3': listar_emp();break;
case '4': /*modificar_emp()*/;break;
case '5': /*borrar_emp()*/;break;
default : gotoxy(24,21);cout <<"Opcion No valida... Presione [ESC]";
mimarco(22,24,22,56,4);
while (getch() != 27);
break;
}
c=menu();
}lp;
}

**************************************************************
 // Programa ejemplo para crear un archivo de acceso directo. Como ejercicio  de programación, el alumno deberá  implementar las funciones borrar() y ordenar() el archivo.

# include <iostream.h>
# include <stdio.h>
# include <conio.h>
# include <dos.h>
# define lp clrscr()
# define g gotoxy

struct articulo
{
int codigo;
char nombre[25];
float precio;
};
int t=sizeof(articulo); // tamaño del registro
int sw=0;;
void grabarArchivo(FILE *fp);
void listarArchivo(FILE *fp);
void actualizar(FILE *fp);
void mostrarArticulo(articulo art);
articulo crearArticulo(FILE *fp);
void mimarco(int t,int l,int b,int r,int f);
void titulos();
fecha();
menu();

int main()
{
FILE *fp;
int op=1;
fp=fopen("c:\\gmv\\archivos\\ARTICULOS.DAT","rb");
if(fp==NULL)
{
g(24,22);cout<< " <<CREANDO ARCHIVO...>> ";
fp=fopen("c:\\gmv\\archivos\\ARTICULOS.DAT","wb"); //si no existe, lo crea.
fclose(fp);
}
fp= fopen("c:\\gmv\\archivos\\ARTICULOS.DAT","r+");
if(fp == NULL)
{
cout<<"Error al abrir el archivo...";
getche();
return 1;
}

int c=menu();
while (c != 27){
switch(c){
case '1': grabarArchivo(fp);break;
case '2': listarArchivo(fp);break;
case '3': actualizar(fp);break;
case '4': /*borrar()*/;break;
case '5': /*ordenar()*/;break;
default : gotoxy(24,21);cout <<"Opcion No valida... Presione [ESC]";
mimarco(22,24,22,56,4);
while (getch() != 27);
break;
}
c=menu();
}lp;
fclose(fp);
return 0;
}

void grabarArchivo(FILE *fp)
{
int codiaux = sw = 0 ;
articulo art;
art = crearArticulo(fp);
if(sw != 1){
fseek(fp,0,SEEK_END);
codiaux = fwrite(&art,t,1,fp);
if(codiaux != 0 )
{
g(15,14);cout<<"Registro grabado..." ;
getche();
}}
}

void listarArchivo(FILE *fp)
{
articulo art;
int codiaux = 0;
fseek(fp,0,SEEK_SET);
while(fread(&art, t,1,fp))
{
mostrarArticulo(art);
getche();
}
g(15,14);cout<<"Listo!...";
getche();
}

void mostrarArticulo(articulo art)
{
lp;
g(15,6);cout <<"DATOS DEL ARTICULO";
titulos(); g(35,8);
cout<<art.codigo; g(35,9);
cout<<art.nombre; g(35,10);
cout<<art.precio; g(35,11);
}

void actualizar(FILE *fp)
{
int codiaux = 0, cont = 1;
articulo art;
lp;
g(15,5); cout <<"CONSULTA POR CODIGO";
g(15,10); cout <<"CODIGO del articulo a modificar -> ";
cin>>codiaux;
fseek(fp,0,SEEK_SET);
while((fread(&art, t,1,fp))&&(cont<codiaux))
{
cont++;
}
mostrarArticulo(art);
g(15,12); cout <<"Nuevo PRECIO? -> $";
g(35,12);cin>>art.precio;
fseek(fp,-t,SEEK_CUR);
codiaux = fwrite(&art,t,1,fp);
if(codiaux != 0 )
{
g(15,14);cout<<"Dato grabado..." ;
getche();
}
}

articulo crearArticulo(FILE *fp)
{
articulo art; int codiaux,cont = 1;
lp;
g(15,6);cout <<"DATOS DEL ARTICULO";
titulos(); //Llama la función titulos()
g(35,8); cin>>codiaux;
fseek(fp,0,SEEK_SET);
while((fread(&art, t,1,fp))&&(cont<codiaux))
{
cont++;
}
if (codiaux == art.codigo){
mostrarArticulo(art);
g(15,14);cout<<"Articulo ya existe!!!..." ;getche();
sw=1;}
else{
art.codigo=codiaux;
g(35,9); gets(art.nombre);
g(35,10);cin>>art.precio;}
return art;
}

void mimarco(int t,int l,int b,int r,int f){
int col=l;
if (f==1){
gotoxy(l,t);printf("É");gotoxy(r,t);printf("»");
gotoxy(l,b);printf("È");gotoxy(r,b);printf("¼");
for (++l;l<r;++l){
gotoxy(l,t);printf("Í");gotoxy(l,b);printf("Í");
}
for (++t;t<b;++t){
gotoxy(col,t);printf("º");gotoxy(r,t);printf("º");
}
}else{
if (f==2){
gotoxy(l,t);printf("Ú");gotoxy(r,t);printf("¿");
gotoxy(l,b);printf("À");gotoxy(r,b);printf("Ù");
for (++l;l<r;++l){
gotoxy(l,t);printf("Ä");gotoxy(l,b);printf("Ä");
}
for (++t;t<b;++t){
gotoxy(col,t);printf("³");gotoxy(r,t);printf("³");
}
}else{
if (f==3){
++r;
for (l;l<r;++l){
gotoxy(l,t);printf("Í");
}
}else{
if (f==4){
++r;
for (l;l<r;++l){
gotoxy(l,t);printf("Ä");
}}}}}
}

void titulos(){
mimarco(1,1,24,80,1);
g(15,8); cout <<"CODIGO :";
g(15,9); cout <<"NOMBRE :";
g(15,10); cout <<"PRECIO $";
}

int fecha(){
struct date d;
getdate(&d);
gotoxy(20,23);printf("%2d/%02d/%02d", d.da_year, d.da_day, d.da_mon);
return 0;
}
int hora(){
struct time t;
while(!kbhit()){
gettime(&t);
gotoxy(59,23);printf("%2d:%02d:%02d",t.ti_hour, t.ti_min, t.ti_sec);
}return 0;
}

menu(){
int c;
textbackground(BLUE);textcolor(WHITE);
lp;
mimarco(1,1,24,80,1);
textcolor(LIGHTBLUE);textbackground(BLACK);
gotoxy(34,1); cprintf("Pengin Soft");
gotoxy (21, 5); cout <<" U N I V E R S I D A D DE I B A G U E";
gotoxy (31, 6); cout <<"<CORUNIVERSITARIA>";
gotoxy (31, 8); cout <<"Archivo de ARTICULOS";
mimarco(10,32,16,49,2);
gotoxy (34,11); cout <<"[1] Adicionar";
gotoxy (34,12); cout <<"[2] Listar";
gotoxy (34,13); cout <<"[3] Modificar";
gotoxy (34,14); cout <<"[4] Borrar";
gotoxy (34,15); cout <<"[5] Ordenar";
gotoxy (29,17); cout <<"Escoja su opcion... [ ]";
gotoxy (24,19); cout <<"Para terminar, pulse la tecla [ESC]";
textcolor(LIGHTBLUE);textbackground(BLACK);
gotoxy(41,24); cprintf("GMV");
fecha(); hora();
gotoxy(51,17);c=getch();
return c;
}

-----------------------------------------------------------------------------------

<> USO DE ARGUMENTOS DE LÍNEA DE COMANDOS

 En muchos sistemas operativos (UNIX y DOS en particular), es posible pasar argumentos a main desde una línea de comandos incluyendo los parámetros int argc y char *argv[] en la lista de parámetros de main. El parámetro argc recibe el número de argumentos de línea de comandos. El parámetro argv es un arreglo de cadenas en donde se almacenan los argumentos de línea de comandos reales. Los usos comunes de los argumentos de línea de comandos son: La impresión de los argumentos, el paso de opciones a un programa y el paso de nombres de archivo a un programa.

El siguiente es un  programa ejemplo con argumentos de línea de comandos:

// Escribir un programa que reciba dos argumentos desde la  linea de comandos, los    // compare e informe cuál es más grande lexicográficamente.
#include "iostream.h"
#include "conio.h"
#include "string.h"
#include "stdlib.h"
#define L clrscr()

void main(int argc, char *argv[])
{
  L;
  int s;
  if(argc!=3){
    cout << "Error! tiene que especificar dos argumentos...";
    getch(); exit(1);
  }
  s=strcmp(argv[1], argv[2]);
  if(s<0)
    cout <<argv[2]<<" > "<<argv[1];
  else if(s>0)
           cout <<argv[1]<<" > "<<argv[2];
        else
           cout <<"Los argumentos son iguales!";
getch();
}

// El siguiente programa lee un archivo y muestra su contenido
// en la pantalla caracter por caracter.
#include "iostream.h"
#include "stdio.h"
#include "conio.h"
#include "stdlib.h"
#define L clrscr()

void main(int argc, char *argv[])
{
  L;
  FILE *fp;  char car;
  if(argc!=2){
     cout << "Error!!! tiene que especificar dos argumentos...";
     getch(); exit(1);
  }
  if((fp=fopen(argv[1],"r"))==NULL){
     cout <<"No se puede abrir el archivo "<<argv[1];exit(1);
  }
  car=getc(fp);         // lee un caracter
  while(car!=EOF){
          putchar(car); // muestra el caracter en la pantalla
          car=getc(fp);
  }
  fclose(fp);
  getch();
}

-----------------------------------------------------------------------------------

1.   El  ISP (Proveedor de Servicios de Internet) Pengüinet.Com requiere un programa para el control de sus clientes, de los cuales registra en un archivo: Cédula, nombre, horas de navegación (mes), valor pagado, fecha de pago y servicio más usado (Web, Chat, ó Correo electrónico). El programa debe realizar:

a) Imprimir el porcentaje de clientes que usaron más el servicio de correo electrónico.

b) Visualizar el nombre del usuario que más pagó.

c) Cuántos clientes pagaron un valor superior al promedio recaudado por el ISP.

d) ¿Cantidad total de horas navegadas?

e) LLamar a una función para que retorne el nombre del servicio menos utilizado.

 

2.  Guardar en un archivo el registro de los libros de una biblioteca. Diseñar un menú con las opciones de Adicionar, Consultar (por código/título/autor), Modificar, Borrar, Ordenar (por código/título/autor)  e Imprimir registros del archivo.


Arriba  


Inicio | Biografía | Cursos | Para pensar... | Para reflexionar... | Para reir | Enlaces

 
Profesor Gustavo Martínez Villalobos
Email: gmartin@nevado.cui.edu.co
Facultad de Ingeniería de Sistemas, Coruniversitaria
Ibagué, Tolima, COLOMBIA