República Bolivariana de Venezuela

Universidad Nacional Experimental del Táchira

Departamento de Ingeniería Informática

Computación II-Ingeniería Electrónica (415201)
San Cristóbal-Venezuela

 

 

 

 

 

 

 

 

 

Archivos

 

 

 

 

 

 

 

 

 

Tema Perteneciente a la Unidad I: Programación Avanzada en Lenguaje C.

 

 

 

 

 

 

 

 

 

 

 

 

Autor: Lcdo. José Froilán Guerrero Pulido

 

 

 

Abril, 2005


 

 

 

 

Qué son los Archivos?

 

El almacenamiento de datos en variables y en arreglos es temporal; al terminar un programa todos estos datos se pierden. Cualquier conjunto de datos almacenado en un dispositivo de almacenamiento secundario, independientemente de la información que represente (programas, textos o gráficos), está agrupado un una estructura de datos llamada archivo. Un archivo es una cadena de bytes consecutivos terminada por un carácter especial llamado EOF (End of File). Por tanto, los archivos de datos nos permiten: a) Almacenar información de modo permanente y acceder y alterar la misma cuando sea necesario; y b) Capacidad de procesar una gran cantidad de datos que de otra manera serían imposibles de manejar.

El lenguaje C incorpora potentes funciones que facilitan mucho la gestión de archivos. Entre estas funciones se puede hacer la siguiente clasificación: a) Funciones de alto nivel o estándar: Son las más utilizadas, por su  fácil implementación. Al programador no le hace falta controlar los buffers ni las conversiones de datos; y b) Funciones de bajo nivel: Son mucho más próximas a las funciones que utiliza el sistema operativo para gestionar archivos; requieren más control por parte del programador, el código, por decirlo de alguna manera, se hace más duro. A veces pero, es más conveniente la utilización de estas funciones ya que permiten un grado de control más alto, en cuanto a como y cuando se han de guardar los datos, además  la velocidad de los accesos a disco es más rápida.

 

Tipos de Acceso a los Archivos

 

·        Acceso Secuencial: En un archivo de acceso secuencial es posible leer o escribir un cierto número de datos al final del archivo (esto implica recorrer todo el archivo, lo que implica tener poca eficiencia).

·        Acceso Directo: Es un tipo de acceso que permita acceder directamente a cualquier posición dada de un archivo. A menudo este tipo de acceso se usa con archivos sin formato en los cuales los datos se organizan en bloques de bytes contiguos de información, con el uso de las estructuras de datos. Los registros individuales de un archivo de acceso directo normalmente son de longitud fija y se puede tener acceso a ellos directamente sin tener que buscar a través de campos individuales. Los datos almacenados también pueden ser agregados, consultados, actualizados o borrados sin tener que reescribir todo el archivo. 

 

 

0

100

200

300

400

500

600

 

Bloque 1

Bloque 2

Bloque 3

Bloque 4

Bloque 5

Bloque 6

 

 

100 bytes

100 bytes

100 bytes

100 bytes

100 bytes

100 bytes

 

 

 

Tipos de Archivo

 

Los archivos se pueden abrir en modo texto, o en modo binario. Esta distinción tiene origen en las primeras versiones de C desarrolladas para el sistema operativo UNIX,  que utilizaba el modo texto; después MS-DOS utilizó el modo binario. Con el lenguaje C se puede abrir un archivo de las dos formas. Las diferencias entre el modo texto y el modo binario son básicamente:

 

·        Texto: Esta primera categoría los caracteres pueden interpretarse como datos individuales, como componentes de una cadena de caracteres o como números. En modo texto, los números se guardan en disco como cadenas de caracteres; por ejemplo, el número 6590 se guarda dígito a dígito, esto quiere decir el carácter 6, el carácter 5, el carácter 9 y el carácter 0, cada dígito se guarda en un byte, ocupando, en este caso concreto, cuatro bytes. Esto quiere decir, entre otras cosas, que toda la información almacenada en un archivo de texto puede ser visualizada por un procesador de textos o un editor cualquiera, de la misma manera que se visualiza la información de un archivo que contiene un programa fuente de C.

·        Binario: En este tipo de archivos no se almacenan los números como cadenas de caracteres sino que se almacenan de la misma forma que se hace en memoria, es decir,  un valor se guarda tal y como está en memoria. Por ejemplo, el número visto anteriormente (6590), se guarda tal y como se representa en memoria, y con cuatro bytes (que es lo que ocupa un dato tipo int). El contenido de los archivos binarios no puede ser visualizado mediante un editor de textos.

 

A continuación se le presentan en tamaño en bytes de cada uno de tipos de datos en lenguaje C. Estos tamaños pueden variar entre diferentes clases de computadoras.

 

 

Tipo de Dato

Tamaño en Bytes

char

1

short

2

int

4

unsigned

4

long

4

float

4

double

8

 

 

Apertura y Cierre de un Archivo

 

FILE  *nombre_puntero;  // Establecer área de búffer.

 

Un área de búffer es un lugar donde la datos se almacenan temporalmente mientras se está transfiriendo entre la memoria de la computadora y el dispositivo donde se encuentra el archivo de datos. FILE es un tipo especial de estructura que establece el área de búffer y nombre_puntero es la variable que indica el principio de esta área. 

 

nombre_puntero = fopen ( “nombre-archivo”,”tipo-apertura”); // Apertura de un archivo.

 

La instrucción anterior asocia el nombre del archivo con el área de búffer. Si la función devuelve un valor NULL significa que no se puede abrir el archivo o este no se encuentra en el lugar señalado.

 

A continuación se presentan las especificaciones para los tipos de apertura, según el tipo de archivo utilizado:

 

 

Archivo de Texto

Archivo Binario

Significado

“w”

“wb”

Abrir un nuevo archivo para escritura. Si el archivo existe será destruido.

“w +”

“wb+”

Abrir un nuevo archivo para escritura/lectura. Si el archivo existe será destruido.

“r”

“rb”

Abrir un archivo existente para lectura.

“r +”

“rb+”

Abrir un archivo existente tanto para lectura/escritura.

“a”

“ab”

Abrir un archivo existente para escritura de datos al final del archivo. Se crea un nuevo archivo si no existe.

“a +”

“ab+”

Abrir un archivo existente para escritura/lectura de datos al final del archivo. Se crea un nuevo archivo si no existe.

 

 

fclose (nombre_puntero);  // Cierre de un archivo.

 

Es buena práctica de programación cerrar los archivos de datos mediante la función fclose, aunque la mayoría de los compiladores cierran automáticamente los archivos de datos al final de la ejecución del programa.

 

Escritura y Lectura en un Archivo

 

Cuando se lee un archivo, se lee realmente el buffer, de la misma manera cuando se escribe en un archivo, se está escribiendo en el buffer. Los datos, no se guardan directamente en el disco, se guardan en un buffer (zona de memoria), y cuando el buffer está lleno, es cuando los datos pasan al disco. De la misma manera, cuando se lee un archivo, todo un bloque de datos del disco pasan al buffer, y desde el buffer, es de donde se leen.

 

while (!feof (nombre_puntero))  // Ciclo para recorrer un archivo en forma secuencial.

{

      Instrucciones de escritura/lectura sobre el archivo de datos;

}

 

La función feof permite indicar el fin de archivo al que esta referido el nombre del puntero. La función regresa un valor no cero (verdadero) una vez definido el indicador de fin de archivo; de lo contrario regresa cero.

 

En la E/L estándar se utilizan funciones de alto nivel, recuerde que son más sencillas de utilizar que las de bajo nivel, pero que también son menos flexibles.

 

 

E/L de caracteres. Las funciones siguientes sirven para guardar datos en un archivo de texto. Los datos siempre se guardaran como tiras de caracteres.

 

La función de escritura para caracteres es:  fputc(caracter, nombre_puntero);

 

La función de  lectura   para caracteres es:  caracter=fgetc(nombre_puntero);

 

E/L de cadenas. Estas funciones pueden simplificar mucho la escritura y lectura de cadenas de caracteres.

 

La función de escritura para cadenas es: fputs(caracter, nombre_puntero);

La función de lectura para  cadenas es: fgets(cadena, numero_caracteres, nombre_puntero);

 

E/L con formato. Estas funciones son muy útiles cuando se han de guardar datos de diferentes tipos de datos en un archivo de texto.

 

fprintf (nombre_puntero ,“formatos de salida y/o secuencias de escape”,var1,var2,..,varN); ó

fprintf (nombre_puntero ,“mensajes y/o secuencias de escape”,var1,var2,..,varN); 

 

La función fprintf es equivalente al printf, excepto que fprintf también recibe como argumento un apuntador de archivo para el archivo al cual se escribirán los datos.

 

fscanf (nombre_puntero ,“formatos de entrada”,&var1,&var2,..,&varN); 

 

La función fscanf es equivalente al scanf, excepto que fscanf también recibe como argumento un apuntador de archivo para el archivo del cual se van a leer los datos.

 

E/L de registros. Todas las funciones vistas hasta ahora, guardan los números en forma de cadenas de caracteres ocupando cada elemento un byte. Esta es una manera, no demasiado eficiente. Si se quisiera guardar arrays numéricos, no quedaría otro remedio que tratar cada elemento de manera individual; si se quisiera guardar estructuras, se tendría que hacer por partes. La solución a estos problemas está en utilizar las funciones de E/L de registros. Estas funciones guardan los valores en formato binario, así, un entero o un float se guarda siempre en cuatro bytes, etc. Las funciones de registros permite la escritura y lectura de cualquier cantidad de bytes a la vez, estas funciones no están limitadas para hacerlo carácter a carácter, ni a hacerlo en una cadena, ni en grupos de valores formateados utilizando las funciones fprintf y fscanf.

Las funciones utilizadas permiten leer y escribir en el disco una estructura (o más) cada vez. Recuerde que estas funciones, guardan los datos en formato binario.

 

fwrite (&variable_tipo_estructura, sizeof (struct nombre_estructura),1, nombre_puntero); 

fread  (&variable_tipo_estructura, sizeof (struct nombre_estructura),1, nombre_puntero); 

 

La función fwrite y fread escribe y lee un número especificado de bytes. Cada una de estas funciones necesita cuatro argumentos: una variable relacionada con el bloque de datos (estructura), el tamaño del bloque de datos, el número de bloques a transferir y el puntero del archivo de datos. Por otra parte, la función sizeof retorna el número de bytes del argumento asignado.

 

fseek (nombre_puntero, sizeof (struct nombre_estructura), nombre_del_indicador); 

 

La función fseek define el apuntador de posición de archivo a una posición especifica dentro del archivo. El último argumento de la función puede tener uno de los siguientes tres parámetros que se  presentan a continuación:

 

SEEK_SET: Indica que la búsqueda se inicia al principio del archivo.

SEEK_CUR: Indica que la búsqueda se inicia en la posición actual del archivo.

SEEK_END: Indica que la búsqueda se inicia al final del archivo.

 

Durante la ejecución de un programa pudiera ser deseable procesar los datos secuencialmente en un archivo varias veces a partir del principio del archivo. Esta operación se puede efectuar con la siguiente función:

 

rewind (nombre_puntero);    // Indica que la búsqueda se inicia al principio del archivo.

 

 

 

Ejercicios Resueltos

 

/* Programa 1: Programa para conocer el tamaño en bytes de los tipos de datos de C/C++ */

 

#include <stdio.h>

#include <conio.h>

 

struct datos

{

     char a;

     short b;

     int c;

     double d;

};

 

void main()

{

     printf("Tipo de dato char tamaño en bytes es de %d\n",sizeof(char));

     printf("Tipo de dato short tamaño en bytes es de %d\n",sizeof(short));

     printf("Tipo de dato int tamaño en bytes es de %d\n",sizeof(int));

     printf("Tipo de dato unsigned tamaño en bytes es de %d\n",sizeof(unsigned));

     printf("Tipo de dato long tamaño en bytes es de %d\n",sizeof(long));

     printf("Tipo de dato float tamaño en bytes es de %d\n",sizeof(float));

     printf("Tipo de dato double tamaño en bytes es de %d\n",sizeof(double));

     printf("Tipo de dato struct tamaño en bytes es de %d\n",sizeof(struct datos));

     printf("\nPresione una Tecla para Continuar");

     getch();

}

 

 

/* Programa 2: Escritura y Lectura caracter a carácter desde un archivo de texto */

 

#include <stdio.h>

#include <conio.h>

#include <string.h>

 

void main()

{

    FILE *archivo;

    char caracter;

    clrscr();

    archivo=fopen("letras.txt","w");

    for (caracter='A'; caracter<='Z'; caracter++)

         fputc(caracter,archivo);

    fclose(archivo);

    archivo=fopen("letras.txt","r");

    for (int i=1;i<=26; i++)

    {

         caracter=fgetc(archivo);

         printf("%c ",caracter);

    }

    fclose(archivo);

    printf ("\n\nPresione una Tecla para Continuar");

    getch();

}

 

/* Programa 3: Escritura de cadenas de caracteres en un archivo de texto */

 

#include <stdio.h>

#include <string.h>

#include <conio.h>

 

void main()

{

  FILE *archivo;

  char cadena[80],nombre_archivo[15];//Variable para capturar el nombre del archivo

  clrscr();

  printf("\nEste programa captura cadenas del teclado y la graba en el archivo");

  printf("\n\nAnote el nombre del archivo (incluyendo la respectiva extension):");

  gets(nombre_archivo);

  archivo=fopen(nombre_archivo,"w");

  printf("\n\nEscriba la cadena de caracteres y presione Enter:");

  while(strlen(gets(cadena))>0) //Ciclo mientras la longitud de la cadena sea > a 0

  {

       fputs(cadena,archivo);   // Graba la cadena capturada en el archivo

fputs("\n",archivo);      

printf("Escriba otra cadena de caracteres:");

  }

  fclose(archivo); // Cierra el archivo

  printf ("\n\nOprima cualquier tecla para continuar");

  getch();

}

 

 

/* Programa 4: Guardar los datos de un grupo de amigos a un nuevo archivo de texto. Los datos a cargar en el archivo son el nombre del amigo y su respectiva edad */

 

#include <stdio.h>

#include <conio.h>

 

void cargar   ();

 

void main()

{

     cargar();

     printf ("\n\nPresione una Tecla para Continuar");

     getch();

}

 

void cargar ()

{

     static int j=0;

char nombre[12],sn;

     int edad;

     FILE *entrada;

     entrada = fopen ("datos.txt","w");

     do

     {

        clrscr();

        ++j;

        printf ("\t\t Amigo Numero %d\n",j);

        printf ("Nombre:");

        scanf  ("%s",&nombre);

        printf ("Edad:");

        scanf  ("%d",&edad);

        fprintf (entrada,"%-3d %-14s %-4d\n",j,nombre,edad);

        printf ("Desea procesar otro amigo (s/n)\?");

        scanf  ("%s",&sn);

        sn=toupper(sn);

     } 

while  (sn=='S');

     fclose(entrada);

}

 

NOTA: Revisar directamente después de ejecutar el programa los datos almacenados en el archivo datos.txt

 

 

/* Programa 5: Listar por pantalla los datos del archivo de texto cargados en el ejercicio anterior */

 

#include <stdio.h>

#include <conio.h>

 

void listar ();

 

void main()

{

     listar();

     printf ("\n\nPresione una Tecla para Continuar");

     getch();

}

void listar ()

{

     int c,e;

     char nom[12];

     FILE *lis;

     lis = fopen ("datos.txt","r");

     if (lis==NULL)

         printf ("\nERROR: El archivo de Datos no Existe");

     else

     {

         printf ("\t  Listado de Amigos\n\n");

         printf ("\tAMIGO\tNOMBRE\t EDAD\n");

         while (!feof(lis))

         {

            fscanf (lis,"%d%s%d",&c,&nom,&e);

            printf ("\t%3d\t%s\t  %-3d\n",c,nom,e);

         }

     }

     fclose (lis);

}

 

 

/* Programa 6: Consultar la edad de un amigo a través de su respectivo nombre. Asumir que el archivo de texto contiene nombres diferentes */

 

#include <stdio.h>

#include <conio.h>

#include <string.h>

 

void consultar();

 

 

void main()

{

     consultar();

     printf ("\n\nPresione una Tecla para Continuar");

     getch();

}

 

void consultar ()

{

     int c,e,enc=0;

     char nom[12],tem[12];

     FILE *con;

     con = fopen ("datos.txt","r");

     if (con==NULL)

         printf ("\nERROR: El archivo de Datos no Existe");

     else

     {

         printf ("Indique el nombre del amigo:");

         scanf ("%s",&tem);

         while (!feof(con))

         {

            fscanf (con,"%d%s%d",&c,&nom,&e);

            if (strcmp(nom,tem)==0)

            {

                enc=1;

                break;

            }

         }

         if (enc==1)

            printf ("\n\nLa edad de %s es %d",nom,e);

         else

            printf ("\n\nEste Amigo no esta Registrado");

     }

     fclose (con);

}

 

 

/* Programa 7: Modificar la edad de un amigo a través de su nombre. Asumir que el archivo de texto contiene nombres diferentes */

 

#include <stdio.h>

#include <conio.h>

#include <string.h>

#include <process.h>

 

int  contar ();

void modificar(int);

 

void main()

{

     static int ult=contar();

     if (ult!=0) modificar (ult);

     printf ("\n\nPresione una Tecla para Continuar");

     getch();

}

 

int contar ()

{

     int c=0,e;

     char nom[12];

     FILE *com;

     system ("del tempo*.txt");

     system ("copy datos.txt tempo1.txt");

     clrscr();

     com = fopen ("tempo1.txt","r");

     if (com==NULL)

         printf ("\nERROR: El archivo de Datos no Existe");

     else

     {

         while (!feof(com)) fscanf (com,"%d%s%d",&c,&nom,&e);

     }

     fclose (com);

     return c;

}

 

void modificar (int u)

{

     int c,e,enc=0;

     char nom[12],tem[12];

     FILE *mod, *aux;

     mod = fopen ("tempo1.txt","r");

     aux = fopen ("tempo2.txt","w");

     printf ("Indique el nombre del amigo:");

     scanf ("%s",&tem);

     while (!feof(mod))

     {

         fscanf (mod,"%d%s%d",&c,&nom,&e);

         if (strcmp(nom,tem)==0)

         {

             enc=1;

             printf ("\n\nLa edad de %s es %d",nom,e);

             printf ("\n\nIndique la nueva edad de %s:",nom);

             scanf  ("%d",&e);

         }

         fprintf (aux,"%-3d %-14s %-4d\n",c,nom,e);

         u--;

         if (u==0) break;

     }

     if (!enc) printf ("\n\nEste Amigo no esta Registrado");

     fclose (aux);

     fclose (mod);

     system ("del datos.txt");

     system ("rename tempo2.txt datos.txt");

}

 

 

/* Programa 8: Operaciones básicas con archivos binarios por medio del uso de estructuras */

 

#include "stdio.h"

#include "conio.h"

#include "string.h"

#include "ctype.h"

#include "dos.h"

 

void incluir();

void consultar();

void modificar();

void eliminar();

 

struct datos

{

    char cedula[10];

    char nombre[12];

    float sueldo;

    int nr,activo;

}clientes;

 

void main()

{

     clrscr();

     printf ("OPERACIONES SOBRE ARCHIVOS\n\n");

     incluir();

     consultar();

     modificar();

     eliminar();

}

 

void incluir()

{

   char ced[10],resp='S';

   FILE *fptr;

   fptr=fopen("clientes.dat","rb+");

   if (fptr==NULL)

   {

       printf ("ERROR: El archivo no existe");

       printf("\nDesea crear el archivo clientes.dat (S/N):");

       resp=toupper(getch());

       if (resp=='S') fptr=fopen("clientes.dat","wb+");

   }

   if (resp=='S')

   {

       do

       {

            int enc=0;

            clrscr();

            printf ("** AGREGAR CLIENTES**");

            printf("\nDar Cedula, 0 para salir:");scanf ("%s",&ced);

            if (strcmp(ced,"0")==0) break;

            rewind(fptr);

            while (!feof(fptr))

            {

               fread(&clientes,sizeof(struct datos),1,fptr);

               if (strcmp(clientes.cedula,ced)==0&&clientes.activo)

               {

                   printf ("\nEste numero de cedula ya esta registrado");

                   enc=1;

                   getch();

                }

                if (enc==1) break;

            }

            if (!enc)

            {

               fptr=fopen("clientes.dat","ab+");

               printf("Dar Nombre:");scanf ("%s",&clientes.nombre);

               printf("Dar Sueldo:");scanf ("%f",&clientes.sueldo);

               strcpy(clientes.cedula,ced);

               clientes.activo=1;          // Activo

               fwrite(&clientes,sizeof(struct datos),1,fptr);

            }

            printf ("\nDesea procesar otro cliente (S/N):");

            resp=toupper(getch());

       }

       while (resp=='S');

   }

   fclose(fptr);

}

 

void consultar()

{

   char ced[10],resp;

   FILE *fptr;

   fptr=fopen("clientes.dat","rb");

   if (fptr==NULL)

   {

       printf ("ERROR: El archivo no existe");

       getch();

   }

   else

   {

       do

       {

            int enc=0;

            clrscr();

            printf ("** CONSULTAR CLIENTES**");

            printf("\nDar Cedula, 0 para salir:");scanf ("%s",&ced);

            if (strcmp(ced,"0")==0) break;

            rewind(fptr);

            while (!feof(fptr))

            {

               fread(&clientes,sizeof(struct datos),1,fptr);

               if (strcmp(clientes.cedula,ced)==0&&clientes.activo)

               {

                   printf ("\nNombre:%s",clientes.nombre);

                   printf ("\nSueldo:%.2f",clientes.sueldo);

                   enc=1;

                   getch();

               }

               if (enc==1) break;

            }

            if (enc==0)

            {

               printf ("\nEste cliente no esta registrado");

               getch();

            }

            printf ("\nDesea consultar otro cliente (S/N):");

            resp=toupper(getch());

       }

       while (resp=='S');

   }

   fclose(fptr);

}

 

void modificar()

{

   char ced[10],resp;

   FILE *fptr;

   fptr=fopen("clientes.dat","rb+");

   if (fptr==NULL)

   {

       printf ("ERROR: El archivo no existe");

       getch();

   }

   else

   {

       do

       {

            int enc=0,i=-1;

            clrscr();

            printf ("** MODIFICAR DATOS DE CLIENTES**");

            printf("\nDar Cedula, 0 para salir:");scanf ("%s",&ced);

            if (strcmp(ced,"0")==0) break;

            rewind(fptr);

            while (!feof(fptr))

            {

               fread(&clientes,sizeof(struct datos),1,fptr);

               i++;

               if (strcmp(clientes.cedula,ced)==0&&clientes.activo)

               {

                   enc=1;

               }

               if (enc==1) break;

            }

            if (enc==0)

            {

               printf ("\nEste cliente no esta registrado");

               getch();

            }

            else

            {

               printf("\nREGISTRO:%d",i+1);

               printf ("\nNombre:%s",clientes.nombre);

               printf ("\nSueldo:%.2f",clientes.sueldo);

               printf ("\nDesea modificar los datos del cliente (S/N):");

               resp=toupper(getch());

               if (resp=='S')

               {

                  printf("\nDar Nombre:");scanf ("%s",&clientes.nombre);

                  printf("Dar Sueldo:");scanf ("%f",&clientes.sueldo);

                  fseek (fptr,i*sizeof(struct datos),SEEK_SET);

                  fwrite(&clientes,sizeof(struct datos),1,fptr);

               }

            }

            printf ("\nDesea modificar datos de otro cliente (S/N):");

            resp=toupper(getch());

       }

       while (resp=='S');

   }

   fclose(fptr);

}

 

void eliminar()

{

   char ced[10],t_nom[12],resp;

   float t_sueldo;

   FILE *fptr;

   int enc, i;

   fptr=fopen("clientes.dat","rb+");

   if (fptr==NULL)

   {

       printf ("ERROR: El archivo de datos no existe");

       getch();

   }

   else

   {

       do

       {

            enc=0;

            i=-1;

            clrscr();

            printf ("** ELIMINAR DATOS DE CLIENTES**");

            printf("\nDar Cedula, 0 para salir:");scanf ("%s",&ced);

            if (strcmp(ced,"0")==0) break;

            rewind (fptr);

            while (!feof(fptr))

            {

               fread(&clientes,sizeof(struct datos),1,fptr);

               i++;

               if (strcmp(clientes.cedula,ced)==0&&clientes.activo)

               {

                   enc=1;

               }

               if (enc==1) break;

            }

            if (enc==0)

            {

               printf ("\nEste cliente no esta registrado");

               getch();

            }

            else

            {

               printf("\nREGISTRO:%d",i+1);

               printf ("\nNombre:%s",clientes.nombre);

               printf ("\nSueldo:%.2f",clientes.sueldo);

               printf ("\nDesea eliminar los datos del cliente (S/N):");

               resp=toupper(getch());

               if (resp=='S')

               {

                  clientes.activo=0;           //Marca lógica

                  fseek (fptr,i*sizeof(struct datos),SEEK_SET);

                  fwrite(&clientes,sizeof(struct datos),1,fptr);

               }

            }

            printf ("\nDesea eliminar datos de otro cliente (S/N):");

            resp=toupper(getch());

       }

       while (resp=='S');

   }

   fclose(fptr);

}

 

 

/* Programa 9: Incluir datos en archivos de texto a través de estructuras */

 

#include "stdio.h"

#include "conio.h"

#include "stdlib.h"

#include "ctype.h"

#include "dos.h"

 

struct datos

{

     long cedula;

     char nom[15],sexo,tel[12];

     int edad;

}archivo;

 

void incluir( );

 

void main( )

{

    char resp;

    do

    {

       clrscr();

       gotoxy(31,3);cprintf(" AGREGAR REGISTROS ");

       gotoxy(31,4);cprintf(" ***************** ");

       incluir( );

       gotoxy(11,22);

       printf("*** Se desea agregar mas datos de otros empleados (S/N) ***:");

       resp=toupper(getch( ));

     }

     while(resp=='S');

}

 

void incluir( )

{

  long num_ced;

  int enc=0;

  FILE *fptr;

  if ((fptr=fopen("empleado.txt","r"))==NULL)

  {

      clrscr( );

      gotoxy(26,23);printf(" *** No existe el Archivo *** ");

      gotoxy(20,24);printf(" ** Pulse cualquier tecla para continuar ** ");

      getche( );

      return;

  }

  else

  {

      gotoxy(3,6);

      printf("** Introduzca el numero de cedula del empleado, 0 para salir **:");

      scanf("%ld",&num_ced);

      if (num_ced==0) return;

      fseek(fptr,sizeof(struct datos),SEEK_SET);

      while (!feof(fptr))

      {

           fread(&archivo,sizeof(struct datos),1,fptr);

           if (num_ced==archivo.cedula)

           {

               gotoxy(26,20);printf(" *** Ya existe el Registro *** ");

               gotoxy(24,21);printf(" ** Pulse una tecla para continuar ** ");

               enc=1;

               break;

           }

      }

      if (!enc)

      {

         fptr=fopen("empleado.txt","a+");

         gotoxy(6,9);printf("Nombre : ");

         scanf("%s",&archivo.nom);

         gotoxy(6,10);printf("Edad : ");

         scanf("%d",&archivo.edad);

         gotoxy(6,11);printf("Sexo : ");

         scanf("%s",&archivo.sexo);

         gotoxy(6,12);printf("Telefono : ");

         scanf("%s",&archivo.tel);

         archivo.cedula=num_ced;

         fwrite(&archivo,sizeof(struct datos),1,fptr);

     }

     fclose(fptr);

  }

}

 

 

/* Programa 10: Listar los registros del archivo de texto del ejercicio anterior en orden secuencial */

 

#include "stdio.h"

#include "conio.h"

#include "stdlib.h"

#include "ctype.h"

#include "dos.h"

 

struct datos

{

     long cedula;

     char nom[15],sexo,tel[12];

     int edad;

} archivo;

 

void listar( );

 

main( )

{

    char resp;

    clrscr();

    gotoxy(31,3);printf(" LISTADO DE REGISTROS ");

    gotoxy(31,4);printf(" ******************** ");

    listar( );

    gotoxy(20,24);printf(" ** Pulse cualquier tecla para continuar ** ");

    getch( );

}

 

void listar( )

{

  long num_ced;

  int enc=0, fil=8;

  FILE *fptr;

  if ((fptr=fopen("empleado.txt","r"))==NULL)

  {

      clrscr( );

      gotoxy(26,23);printf(" *** No existe el Archivo *** ");

      gotoxy(20,24);printf(" ** Pulse cualquier tecla para continuar ** ");

      getch( );

      return;

  }

  else

  {

      gotoxy(2,6);

      printf("   Cedula\t   Nombre\t  Edad\t  Sexo\t   Telefono");

      fseek(fptr,sizeof(struct datos),SEEK_SET);

      while (!feof(fptr))

      {

           fread(&archivo,sizeof(struct datos),1,fptr);

           gotoxy(6,fil);

           printf("%3ld\t  %10s\t\t  %2d\t %2c\t %-10s",archivo.cedula,archivo.nom,

                  archivo.edad,archivo.sexo,archivo.tel);

           fil++;

           enc=1;

      }

      gotoxy(6,fil-1);

      printf("                                                                 ");

      if (!enc)

      {

          gotoxy(26,22);printf(" *** No existen Registros *** ");

      }

      fclose(fptr);

  }

}

 

 

/* Programa 11: Consultar datos en archivos binarios de acceso directo a través de un archivo indice */

 

#include "stdio.h"

#include "conio.h"

#include "stdlib.h"

#include "ctype.h"

 

struct maestro

{

     int no_cuenta;    //Campo Clave

     char nom[15];

     float saldo;

} regpri;

 

struct indice

{

     int no_registro;

     int no_cuenta;     //Campo Clave

} regind;

 

void incluir( );

void consultar( );

 

void main( )

{

  incluir( );

  consultar( );

}

 

void incluir( )

{

  char resp;

  int cuenta,enc;

  static int ult=0;

  FILE *mptr, *iptr;

  mptr=fopen("clientes.dat","wb+");

  iptr=fopen("indice.dat","wb+");

  do

  {

     enc=0;

     clrscr();

     gotoxy(31,3);printf(" AGREGAR CLIENTES ");

     gotoxy(31,4);printf(" **************** ");

     gotoxy(3,6);printf("** Introduzca el numero de cuenta, 0 para salir **:");

     scanf("%d",&cuenta);

     if (cuenta==0) return;

     rewind(mptr);

     while (!feof(mptr))

     {

        fread(&regpri,sizeof(struct maestro),1,mptr);

        if (cuenta==regpri.no_cuenta)

        {

            gotoxy(26,20);printf(" *** Ya existe el Registro *** ");

            gotoxy(24,21);printf(" ** Pulse una tecla para continuar ** ");

            enc=1;

        }

        if (enc) break;

     }

     if (!enc)

     {

         gotoxy(6,9);printf("Nombre : ");

         scanf("%s",&regpri.nom);

         gotoxy(6,10);printf("Saldo : ");

         scanf("%f",&regpri.saldo);

         regpri.no_cuenta=cuenta;

         regind.no_cuenta=cuenta;

         regind.no_registro=++ult;

         fwrite(&regpri,sizeof(struct maestro),1,mptr);

         fwrite(&regind,sizeof(struct indice),1,iptr);

     }

     gotoxy(11,22);

     printf("*** Se desea agregar mas datos de otros clientes (S/N) ***:");

     resp=toupper(getch( ));

  }

  while(resp=='S');

  fclose(mptr);

  fclose(iptr);

}

 

void consultar( )

{

  char resp;

  int cuenta, num, enc;

  FILE *mptr, *iptr;

  mptr=fopen("clientes.dat","rb");

  iptr=fopen("indice.dat","rb");

  do

  {

     enc=0;

     clrscr();

     gotoxy(31,3);cprintf(" CONSULTAR CLIENTES ");

     gotoxy(31,4);cprintf(" ****************** ");

     gotoxy(3,6);printf("** Introduzca el numero de cuenta, 0 para salir **:");

     scanf("%d",&cuenta);

     if (cuenta==0) return;

     rewind(mptr);

     rewind(iptr);

     while (!feof(iptr)&&(!enc))

     {

        fread(&regind,sizeof(struct indice),1,iptr);

        if (cuenta==regind.no_cuenta)

        {

            enc=1;

            num=regind.no_registro;

        }

        if (enc) break;

     }

     if (!enc)

     {

        gotoxy(26,20);printf(" *** El Cliente no Existe *** ");

        gotoxy(24,21);printf(" ** Pulse una tecla para continuar ** ");

     }

     else

     {

        fseek (mptr,(num-1)*sizeof(struct maestro),SEEK_SET);

        fread(&regpri,sizeof(struct maestro),1,mptr);

        gotoxy(6,9);printf("Nombre :%s ",regpri.nom);

        gotoxy(6,10);printf("Saldo :%.2f ",regpri.saldo);

     }

     gotoxy(11,22);

     printf("*** Se desea consultar mas datos de otros clientes (S/N) ***:");

     resp=toupper(getch( ));

  }

  while(resp=='S');

  fclose(mptr);

  fclose(iptr);

}

 

 

/* Programa 12: Determinar la longitud de un archivo en bytes */

 

#include <stdio.h>

#include <io.h>

#include <conio.h>

 

void main()

{

    long num_bytes;

    char entrada[35];

    FILE *teclado;

    printf("Dar Nombre del Archivo:");

    scanf("%s",entrada);

    teclado=fopen(entrada,"r");

    if (teclado==NULL)

        printf("No existe el archivo\n");

    else

    {

        num_bytes=filelength(fileno(teclado));

        printf("El numero de bytes del archivo %s es : %ld", entrada,num_bytes);

    }

    fclose(teclado);

    printf ("\n\nPresione una Tecla para Continuar");

    getch();

}

 

 

 


 

Ejercicios Propuestos

 

1.      Investigar las funciones putw y getw. Diseñar un programa donde se evidencie el uso de las funciones señaladas.

2.      Modificar el programa número cuatro para agregar al final del archivo datos de otros amigos.

3.      Modificar el programa número cinco de tal manera de eliminar la repetición de datos al final del listado.

4.      Modificar el programa número cinco resuelto de tal manera de listar los datos del archivo en orden alfabético por el nombre del amigo. Crear un nuevo archivo con los datos del archivo en forma  ordenada.

5.      Con la estructura de datos del programa número ocho resuelto, ordenar y listar los registros a través de un archivo indice (campo clave: número de cédula).

6.      Programa que copie un archivo A en otro B. El contenido del archivo A es de N caracteres.

7.      Diseñar un programa que, dado un archivo de texto, solicite al usuario una palabra a la vez y cuente el número de las mismas que hay en el archivo.

8.      Sea X un archivo donde se guardan los nombres de N artículos. Los nombres de los artículos se pueden repetir a lo largo del archivo. Hacer un programa que elimine los artículos repetidos.

9.      Dado un archivo Z, cuyos elementos son de tipo carácter ordenados en forma creciente. A partir de este archivo crear mediante un programa otro archivo ordenado en forma decreciente respecto del mismo elemento.

10.  Disenar un programa que, dado un archivo de texto compuesto por frases, compruebe si la primera letra de cada frase es mayúscula, en caso contrario, sustituir la minúscula por la correspondiente mayúscula. (Para este ejercicio es conveniente disponer de una tabla ASCII).

11.  Diseñar un programa donde se aplique el método de ordenación por mezcla directa (merge). El programa se debe desarrollar a través de dos archivos de texto.

12.  Programa que cuente el numero de vocales en un archivo de texto.

13.  Elaborar un programa que lea m<=100 caracteres de un archivo de texto y los almacene en una matriz de tamaño 10x10. El programa debe ordenar la matriz de tal manera que todos los caracteres diferentes de “ “ (espacio en blanco) sean almacenados al comienzo. Se quiere saber cuantas veces se repite la letra “a” en la matriz.

14.  La organización de un concurso canino, lleva un control manual sobre los datos de los ejemplares que son inscritos para concursar, estos son: Nombre del perro, Sexo, Edad, Raza, Características especiales (pedigrí, origen, numero de veces que ha sido campeón). Se necesita que usted diseñe un programa en C para automatizar a través de archivos binarios el proceso y permita:

a.- Almacenar los datos de todos los ejemplares que se presenten al concurso, en un arreglo de registros, en donde haya al menos un campo tipo registro.

b.- Use una función definida por el programador, para mostrar listados separados para las razas “Pastor Aleman”, “Doberman”, “Boxer”, en donde se muestre sus datos. Por ejemplo:

 

Raza: Doberman

   Nombres     Sexo       Edad      Pedigrí         Origen

Roko           M          1             No         Nacional

      Boby           M          2               Si          Importado

 

c.- Utilizando una función definida por el programador, determine si la edad promedio de las perras, de raza “coker” con pedigrí que han sido campeonas, supera al de los perros de raza “chihuahua”, importados; en al menos 45%.