Asignatura
Taller de Computación II
Módulo III
Archivos
Elaboración
Gabriel F. Stancanelli
Aporte del profesor Fabian Gentile al material de este módulo.
Este material pertenece a la materia Taller de Computación II de la Carrera de Analista de Sistemas de Computación de
Educación a Distancia del INSTITUTO DE TECNOLOGÍA ORT.
Todos los derechos reservados. No esta permitida la reproducción total o parcial de este apunte, ni su tratamiento informático, ni
la transmisión de ninguna forma o por cualquier medio, ya sea electrónico, mecánico, por fotocopia, por registro u otros métodos,
sin el permiso previo de los titulares.
3da edición Agosto de 2010.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Unidad didáctica III: Archivo
Pag. 1
UNIDAD DIDÁCTICA III
ÍNDICE
UNIDAD DIDÁCTICA III .................................................................................................................... 2
ÍNDICE ................................................................................................................................................................................................. 2
Introducción y orientaciones para el estudio............................................................................................................................ 3
Objetivos ....................................................................................................................................................................................... 3
Aclaraciones previas al estudio............................................................................................................................................. 3
Más tipos de datos ........................................................................................................................................................................... 4
Estructuras ...................................................................................................................................................................................... 4
Conversión de tipos (casts) .......................................................................................................................................................... 6
Archivos .............................................................................................................................................................................................. 8
Primero: Operaciones con archivos ............................................................................................................................................ 8
Segundo: Organización de archivos ........................................................................................................................................... 8
Tercero: Tipo de archivos ............................................................................................................................................................. 8
Cuarto: Almacenamiento en archivos ......................................................................................................................................... 9
Quinto: Modularización de las operaciones ............................................................................................................................. 16
Unidad didáctica III: Archivos
Pág. 2
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Introducción y orientaciones para el estudio
En el desarrollo de este módulo abordaremos:
ƒ
ƒ
Variables del tipo Estructuras.
Archivos.
Objetivos
Pretendemos que al finalizar de estudiar esta Unidad, el alumno logre:
ƒ
ƒ
Poder manejar estructuras de datos.
Tener un manejo básico de archivos secuenciales.
Aclaraciones previas al estudio
En este módulo, usted encontrará:
Contenidos
Conceptualizaciones centrales
Bibliografía
Referencia de material bibliográfico recomendado
Actividades
Usted debe tener presente que los contenidos presentados en el módulo no ahondan
profundamente en el tema, sino que pretenden ser un recurso motivador, para que a
través de la lectura del material, la bibliografía sugerida, y el desarrollo de las
actividades propuestas alcance los objetivos planteados en el presente módulo.
Cada módulo constituye una guía cuya finalidad es facilitar su aprendizaje.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 3
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Más tipos de datos
En este capítulo se revisa la forma como pueden ser creados y usados en C++ tipos de
datos más complejos y estructuras.
Estructuras
En C++ una estructura es una colección de variables que se referencian bajo el mismo
nombre. Una estructura proporciona un medio conveniente para mantener junta información que se
relaciona. Una definición de estructura forma una plantilla que se puede usar para crear variables
de estructura. Las variables que forman la estructura son llamados elementos estructurados.
Generalmente, todos los elementos en la estructura están relacionados lógicamente unos
con otros. Por ejemplo, se puede representar una lista de nombres de empleados en una
estructura. Mediante la palabra clave struct se le indica al compilador que defina una plantilla de
estructura.
struct Empleado{
char sNombre[30];
int iEdad;
char sDomicilio[40];
char sCiudad[20];
char cSexo;
int iLegajo;
};
Nota: el punto y coma “;” al finalizar la declaración de la estructura es obligatorio,
ya que sino el programa no compila.
Por convención del curso, le antepondremos “ty_” al nombre de la estructura, para saber
que se trata de un tipo de datos.
struct ty_Empleado{
char sNombre[30];
int iEdad;
char sDomicilio[40];
char sCiudad[20];
char cSexo;
int iLegajo;
};
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 4
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Con la porción de código anterior no ha sido declarada ninguna variable, tan sólo se ha
definido el formato, con lo cual no ocupamos aún espacio en memoria.
Cabe señalar que los campos de una estructura no necesariamente tienen que ser del
mismo tipo de datos, observe que en nuestro ejemplo hay campos que son del tipo integer, string,
char. Para declarar una variable, se hará de la siguiente manera:
struct ty_Empleado tyInfo_empleado;
En C++ no es necesario anteponer la palabra struct para indicar que se trata de una estructura.
ty_Empleado tyInfo_empleado;
Observe que la variable se declara de la misma forma en que lo veníamos realizando:
primero el tipo de dato, y luego el nombre de la variable.
Observar que ty_Empleado es una etiqueta para la estructura que sirve como una forma
breve para futuras declaraciones.
Las variables del tipo estructuras, al igual que las variables vistas anteriormente, pueden
ser preinicializadas en la declaración:
ty_Empleado tyInfo_empleado={"Vicente Fernandez",40,"Corrientes 348","Capital
Federal","M",12345};
Recordar que los literales siempre van encerrados entre comillas dobles, por
ejemplo:
"Corrientes 348"
Para referenciar o acceder a un miembro (o campo) de una estructura, C++ proporciona el
operador punto “.”. Por ejemplo, para asignar a tyInfo_empleado otro legajo, lo hacemos como:
tyInfo_empleado.iLegajo=54321;
Por último, es perfectamente válida la asignación de una variable de tipo estructura a otra
variable del tipo estructura, siempre que ambas sean del mismo tipo.
Por ejemplo:
ty_Empleado tyInfo_empleado1, tyInfo_empleado2;
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 5
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
//Dentro del programa principal. . .
tyInfo_empleado1.sNombre = "JUAN";
tyInfo_empleado1.iEdad
= 33;
tyInfo_empleado1.sDomicilio = "MERCEDES";
tyInfo_empleado1.sCiudad = "BS.AS. ";
tyInfo_empleado1.cSexo
= 'M';
tyInfo_empleado1.iLegajo = 8387;
// y luego realizamos la siguiente asignación. . .
tyInfo_empleado2 = tyInfo_empleado1;
Ahora tyInfo_empleado2 contendrá los mismos valores que tyInfo_empleado1.
Actividad 3 - 1:
-
Declarar una estructura alumno, que contenga los campos matrícula, apellido, sexo y
edad. Solicitar al operador que cargue valores por teclado y luego mostrarlos.
Desarrollar el ejercicio 1 de la Unidad III que se encuentra en la biblioteca de ejercicios.
Conversión de tipos (casts)
C++ es uno de los pocos lenguajes que permiten la conversión de tipos, esto es, forzar una
variable de un tipo a ser de otro tipo. Lo anterior se presenta cuando variables de un tipo se
mezclan con las de otro tipo. Para llevar a cabo esto, se utiliza el operador de conversión (cast) ().
Por ejemplo:
int iNumeroentero;
float fNumeroflotante = 9.87;
iNumeroentero = (int) fNumeroflotante;
Con lo cuál se asigna 9 a la variable iNumeroentero y la fracción es desechada.
El siguiente código:
int iNumeroentero = 10;
float fNumeroflotante;
fNumeroflotante = (float) iNumeroentero;
Asigna 10.0 a fNumeroflotante. Como se observa C++ convierte el valor del lado derecho de la
asignación al tipo del lado izquierdo.
La conversión de tipos puede ser también usada con cualquier tipo simple de datos
incluyendo char, por lo tanto:
int iNumeroentero;
char cLetra = 'A';
iNumeroentero = (int) cLetra;
Asigna 65 (que es el código ASCII de 'A') a iNumeroentero.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 6
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Algunas conversiones de tipos son hechas de forma automática. Esto es,
principalmente, por la característica de compatibilidad de tipos.
Una buena regla es la siguiente: En caso de duda, conversión de tipos.
Una mejor: siempre utilizar conversión de tipos ya que aclara la legibilidad del
código.
Otro uso es asegurarse que la división de números se comporta como se requiere, ya que si
se tienen dos enteros la forma de forzar el resultado a un número flotante es:
fNumeroflotante = (float) iNumeroentero / (float) iDenomentero;
Con lo que se asegura que la división devolverá un número flotante.
Actividad 3 - 2:
-
Solicitar al usuario el ingreso por teclado de un número entero, y luego mostrarlo por
pantalla como un número real.
Actividad 3 - 3:
-
Solicitar al usuario el ingreso por teclado de letras mientras sean distintas de asterisco '
* ', y mostrar el valor ASCII de cada una de ellas.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 7
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Archivos
Si bien es cierto que ya se pueden manejar gran cantidad de datos del mismo y diferente
tipo al mismo tiempo, el problema es que al terminar de ejecutarse el programa los datos se
pierden.
De esta situación nace el concepto de archivos que son medios que facilita el lenguaje para
almacenar los datos en forma permanente.
En general es necesario entender algunos conceptos elementales de sistemas de archivos
tradicionales.
Como nota a tomar en cuenta, los datos que se van almacenando en un archivo de disco, se
almacenan en renglones consecutivos y cada renglón en disco, se conoce como registro del
archivo. Por favor, no confundir el concepto de registro de archivo y registro o estructura como
variable ya analizada, son dos cosas totalmente diferentes aunque desafortunadamente se llamen
igual.
Primero: Operaciones con archivos
ABRIR Y CERRAR: Son las operaciones por las cuales el programa se conectará con y
desconectará del archivo físico que contendrá los datos a grabar o recuperar.
ESCRIBIR O GRABAR: Es la operación mas elemental con un archivo, consiste en tomar un
o unos datos en variables de cualquier tipo (variables sueltas, arreglos, estructuras) y almacenarlas
en un archivo de datos en disco.
LEER: Operación que consiste en recuperar los datos del archivo en disco y mandarlos o
cargar la variable respectiva, que se encuentra en memoria.
Segundo: Organización de archivos
En general existen dos tipos de archivos:
Archivos Secuenciales.- En este caso los datos se almacenan en forma consecutiva y no es
posible leer ningún registro (de un archivo, recuerdan la nota de arriba) directamente, es decir para
leer el registro n se deberá recorrer o acceder los n-1 registros anteriores.
Archivos Directos o Random.- Para este caso, sí se puede acceder o leer un registro n
cualquiera.
Tercero: Tipo de archivos
En general existen tantos tipos de archivos como tipos de datos existen, es decir:
El paquete Standard de input/output de "C", permite disponer de cuatro métodos o maneras
diferentes de leer y escribir los datos a disco.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 8
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Tres de ellas corresponden exactamente a lo aprendido de leer y escribir datos desde el
teclado hacia la pantalla.
1.- Datos a ser grabados o leídos como un carácter a la vez, se utilizarán funciones
análogas a getchar() y putchar().
2.- Datos que pueden ser leídos o grabados como un string, se usarán funciones análogas a
gets() y puts().
3.- Datos que se capturen o desplieguen con formatos parecidos a los usados por scanf() y
printf() se usarán funciones similares, es decir serán problemas que involucran mezclas de strings,
caracteres, floats, etc.
4.- También se podrán leer y escribir datos de tipo arreglo (tema a tratar en la próxima
unidad) y registros utilizando instrucciones apropiadas, en resumen:
caracter
String
Formateado
Registros y
arreglos
Leer
getc()
fgets()
fscanf()
fread()
Escribir
putc()
fputs()
fprintf()
fwrite()
ATENCION: Ya que se decide utilizar algún archivo específico de datos (caracteres, strings,
formateados, registros o arreglos) sólo utilizar las funciones de escritura y lectura de ese tipo de
archivo, por ningún motivo mezcle funciones de lectura y escritura de otro tipo de archivos.
Cuarto: Almacenamiento en archivos
Modo Texto: en este caso los datos son almacenados usando codificación ASCII y por lo
tanto son plenamente visibles usando cualquier editor de textos como ser el edit o notepad.
Modo Binario: en este caso los datos son almacenados en notación binaria (tal como se
guardan en las variables en memoria) y por lo tanto se ocupa un editor binario para reconocerlos,
sin embargo un archivo binario es más compacto que un archivo texto. Estos archivos también son
llamados tipificados.
Para Proposito De Este Curso, Entonces Nos Concentramos En
Archivos De Disco De Registros O Estructuras, Secuenciales, Y
Binarios.
Existen Otros Tipos De Organización (Relativos, Secuenciales
Indexados, Base De Datos), Que Serán Tratados Más Adelante En
Otras Materias De Esta Carrera.
En este capítulo se mostrará una forma de cómo pueden ser creados y leídos en C++ los
archivos secuenciales tipificados (con diseño de registro).
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 9
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Para comenzar la comprensión del tema de archivos vamos a analizar el siguiente código
fuente:
//Incluimos las siguientes librerías para la utilización de rutinas.
#include <iostream>
#include <string.h>
using namespace std;
// Se define el tamaño máximo del string para el nombre
#define MAXNOM 10
// Recuerde que las sentencias al preprocesador, aquellas que comienzan con #, no
// llevan punto y coma “;”, ya que no son parte de C y no cumplen su sintaxis.
// Se define el tipo de datos string para la variable strNombre
typedef char ty_sNombre[MAXNOM];
//armamos un tipo de datos estructuras para los datos de una persona.
typedef struct ty_Persona {
int
iEdad;
char cInicial;
ty_sNombre sNombre;
};
//declaramos los prototipos de las funciones.
void Grabar(ty_Persona p);
ty_Persona Leer();
void main(){
//Se crea la variable p del tipo ty_Persona
ty_Persona p;
system("cls");
//Llenamos a mano el registro
p.iEdad = 3;
p.cInicial = 'A';
strcpy(p.sNombre, "Juan");
// Llamamos a la rutina para grabar el registro en el archivo
Grabar(p);
// Llamamos a la rutina que lee del archivo y se
// a la variable p para luego mostrar los datos
p = Leer();
lo
asignamos
cout << "Leído iEdad: " << p.iEdad << "\n";
cout << "Leído cInicial: " << p.cInicial << "\n";
cout << "Leído sNombre: " << p.sNombre << "\n";
getchar();
}
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 10
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
//Grabar recibe como parámetro una variable del tipo Ty_Persona
void Grabar(ty_Persona dato){
//Creamos la variable ArchSal que es el nombre con el cuál referenciaremos al
// archivo Siempre FILE es con mayúsculas y se coloca el asterisco “ * ”
FILE * ArchSal;
/* A la rutina fopen se le pasa como parámetros la ubicación del archivo y el tipo de
apertura que se utilizará, en nuestro caso es de salida, quiere decir que se escribirá
en el archivo, esto se lo indica con el switch “w”. Tenga en cuenta que si el archivo
no existe lo crea, y en caso contrario lo sobrescribe. La “b” indica que escribiremos
en el archivo en modo binario. */
ArchSal = fopen("c:\\Datos.Dat", "wb");
// La siguiente pregunta es para evaluar si se pudo o no crear el archivo
if (ArchSal == NULL){
cout << "No se pudo abrir el Archivo de Salida.\n";
}else{
fwrite(&dato, sizeof(dato), 1, ArchSal);
/* Parámetros de la rutina fwrite:
&dato: se le pasa la estructura a grabar por dirección
sizeof(dato): se le indica el largo en bytes de la estructura
1: es la cantidad de repeticiones a grabar
ArchSal: en dónde lo graba */
//Cerramos el archivo puesto que no se volverá a utilizar
fclose(ArchSal);
}
}
//Esta rutina leerá del archivo y nos devolverá un registro del tipo ty_Persona
ty_Persona Leer(){
ty_Persona Aux;
//Creamos la variable ArchEnt que es el nombre con el cual
// referenciaremos al archivo
FILE * ArchEnt;
// En este caso a fopen se le pasa como parámetros la ubicación del archivo
// y se le indica mediante "r" que será de sólo lectura y "b" del tipo binario
ArchEnt = fopen("c:\\Datos.Dat", "rb");
//Se comprueba que se pudo abrir el archivo
if (ArchEnt == NULL){
cout << "No se pudo abrir el Archivo de Entrada.\n";
}else{
fread(&Aux, sizeof(Aux), 1, ArchEnt);
/* Parámetros de la rutina fread:
&Aux: se le pasa la estructura por dirección en donde va a dejar los
datos leídos del archivo
sizeof(Aux): se le indica el largo en bytes de la estructura
1: es la cantidad de repeticiones a leer
ArchEnt: en donde va a leer */
//Cerramos el archivo
fclose(ArchEnt);
}
//Devolvemos el valor leído
return Aux;
}
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 11
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
En el ejemplo anterior se abrió el archivo para poder grabar en él un registro, luego se
cerró el archivo para poder abrirlo de entrada, es decir para poder leer el registro que se grabó y
por último lo volvimos a cerrar. Esto se manejó de esta manera porque grabamos sólo un registro
para familiarizarnos con los comandos. Tenga en cuenta, además, que al pasar de un modo de
apertura a otro, como en nuestro caso del ejemplo anterior, primero se deberá cerrar el archivo.
En el siguiente ejemplo grabará registros en el archivo mientras el usuario no ingrese cero
(0) en la edad. Luego cerrará el archivo abierto para la grabación y lo abriremos de lectura para
mostrar los registros grabados en él por pantalla.
En el siguiente ejemplo, a través de un menú de opciones se grabará registros en el archivo
de personas, con datos ingresados por pantalla. El proceso de ingreso de datos finaliza cuando el
usuario ingrese cero (0) en la edad.
La segunda opción es leer todo el archivo y mostrar los datos en la pantalla.
//Incluimos las siguientes librerías para la utilización de rutinas.
#include <iostream>
using namespace std;
//Se define el tamaño máximo del string para el nombre
#define MAXNOM 10
// Recuerde que las sentencias al preprocesador, aquellas que
// comienzan con #, no llevan punto y coma “;”, ya que no son sintaxis.
//Se define un tipo de datos string
typedef char ty_sNombre[MAXNOM];
//armamos un tipo de datos estructuras para el archivo, que
// en este caso coincide para el ingreso.
typedef struct ty_RegPer{
int
iEdad;
char cInicial;
ty_sNombre sNombre;
};
//Prototipos de rutinas.
bool AbrirArchEscrituraPer(FILE * & Arch);
bool AbrirArchLecturaPer(FILE * & Arch); // este proceso abre para
void GrabarRegArchPer(ty_RegPer r, FILE * & f); //lectura,
void LeerRegArchPer(ty_RegPer& r , bool & bFin, FILE * & f);
void CerrarArchPer(FILE *& f);
void MostrarPer (ty_RegPer r);
void Ingresar_DatosPer(ty_RegPer & rPer, bool & finDatos);
void generarArchivoPer () ;
void leerArchivoPer () ;
char menu() ;
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 12
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
void main(){
char op;
do {
op = menu() ;
switch (op) {
case 'g' : { generarArchivoPer() ; break; }
case 'l' : { leerArchivoPer() ; break; }
default : break ;
}
} while (op!='f') ;
getchar();
}
//Desarrollo de Rutinas
bool AbrirArchEscrituraPer(FILE *& Arch){
/*Acá le indicamos en que lugar físico del disco rígido va a almacenar el
archivo que vamos a generar.*/
Arch = fopen("c:\\DatosPer.Dat", "wb");
/*Si Arch es igual a NULL (se estudiará en el próximo cuatrimestre), no se ha
podido abrir el archivo*/
if (Arch == NULL){
cout << "No se pudo abrir el Archivo de Salida.\n";
return false;
} else
return true;
}
bool AbrirArchLecturaPer(FILE *& Arch){
// Ídem rutina anterior
Arch = fopen("c:\\DatosPer.Dat", "rb");
if (Arch == NULL){
cout << "No se pudo abrir el Archivo de Entrada.\n";
return false;
} else
return true;
}
void CerrarArchPer(FILE *& f){
fclose(f);
}
void GrabarRegArchPer(ty_RegPer r, FILE *& f){
// Acá se graba efectivamente el registro en el archivo
fwrite(&r, sizeof(r), 1, f);
/* Parámetros: &p: paso la estructura
sizeof(p): el largo en bytes de la struct
1: la cantidad de repeticiones
ArchSal: en donde lo graba */
}
void LeerRegArchPer(ty_RegPer &r , bool &bFin, FILE *&f){
// Rutina que lee los registros del archivo (uno por vez)
fread(&r, sizeof(r), 1, f);
//Preguntamos si leyó que es fin de archivo o leyó un registro
if (feof(f)) bFin = true;
else
bFin = false;
}
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 13
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
void Ingresar_DatosPer(ty_RegPer & r, bool & finDatos){
do{
cout << "Ingrese la Edad (0=FIN): ";
cin >> r.iEdad;
}while (r.iEdad < 0);
if (r.iEdad !=0){
finDatos = false;
do{
cout << "Ingrese la Inicial: ";
cin >> r.cInicial;
} while (((r.cInicial < 'a') || (r.cInicial > 'z'))
&& ((r.cInicial < 'A') || (r.cInicial > 'Z')));
cout << "Ingrese el Nombre: ";
cin >> r.sNombre;
} else finDatos = true;
}
void MostrarPer (ty_RegPer r){
cout << "\nEdad: " << r.iEdad;
cout << "\nInicial: " << r.cInicial;
cout << "\nNombre: " << r.sNombre;
}
void generarArchivoPer () {
/*Variable para recibir datos de entrada, que coincide con el formato del
archivo que tenemos que crear.*/
ty_RegPer rPer;
bool finDatos;
bool bFin;
//Variable booleana de Fin de ingreso de datos por
// el usuario (cero en la edad)
bool bPudeAbrirArch; //Variable para controlar las aperturas
//de los archivos.
FILE * fPer;
//Variable para el manejo del Archivo
system("cls");
//Se abre el archivo para poder enviarle datos para almacenar
bPudeAbrirArch = AbrirArchEscrituraPer(fPer);
//Consultamos si fue posible la apertura
if (bPudeAbrirArch) {
/*En esta rutina, el usuario ingresará los datos y por tratarse de una
función, se la asignamos a la variable p que esdel mismo tipo que
definimos la función.*/
Ingresar_DatosPer(rPer, finDatos);
/*Mientras el usuario no ingrese cero, grabamos el registro
ingresado por el usuario a través del teclado*/
while (!finDatos){
GrabarRegArchPer(rPer, fPer);
Ingresar_DatosPer(rPer, finDatos);
}
/*Al finalizar el ingreso de datos, como ya no guardaremos más datos en
el archivo, lo cerramos para luego abrirlo de lectura para ver los
resultados.*/
CerrarArchPer(fPer);
}
}
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 14
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
void leerArchivoPer () {
/*Abrimos el archivo de lectura y le asignamos el resultado de esta operación a
bPudeAbrirArch */
ty_RegPer rPer;
bool finDatos;
bool bFin;
//Variable booleana de Fin de ingreso de datos por
// el usuario (cero en la edad)
bool bPudeAbrirArch; //Variable para controlar las aperturas
//de los archivos.
FILE * fPer;
//Variable para el manejo del Archivo
bPudeAbrirArch = AbrirArchLecturaPer(fPer);
/* Traemos un registro para mostrarlo siempre que no sea fin de archivo,
es decir que aún haya mas información.*/
if (bPudeAbrirArch) {
LeerRegArchPer(rPer, bFin, fPer);
// Mientras no sea bFin (variable creada por nosotros para controlar
// el fin de archivo)
while (!bFin) {
MostrarPer(rPer);
LeerRegArchPer(rPer, bFin, fPer);
}
CerrarArchPer(fPer);
getchar();
}
}
char menu() {
char op ;
do {
cout<<"ingrese opcion (f=fin/l=leer/g=grabar)"<<endl;
cin>>op;
} while ((op!='f') && (op!='l') && (op!='g')) ;
return op;
}
Se podrán utilizar para cualquier ejercicio que se necesite manejar archivos. Sólo
bastará con modificar el registro del archivo. Dichas rutinas serán colocadas en internet.
Actividad optativa:
1) Puede implementar la solución, y escribir con sus propias palabras qué
hace cada procedimiento.
2) Puede escribir cuál es la sintaxis de cada instrucción relacionada con los
archivos (fopen, fclose, fread, fwrite). Para esto último debe utilizar la ayuda
en línea del IDE.
3) Puede modificar el programa para que trabaje con un archivo cuyos
campos sean: nombre (30 caracteres, fecha de nacimiento (8 caracteres),
sexo (un carácter ‘v’, ‘m’), y que grabe dos archivos, uno por cada sexo.
4) Puede modificar el listado preguntando que sexo quiere listar, y procesar
el archivo correspondientes.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 15
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
Actividad 3 - 4:
- Realizar los cambios necesarios al programa recientemente explicado, para que grabe un
archivo con los registros erróneos validados en el ingreso. Dejando solamente en el archivo
de datos, aquellos registros que cumplen correctamente con las validaciones, y en un
archivo llamado errores.dat sólo aquellos registros que no cumplieron con las validaciones.
Nótese que al usuario ya no se le volverá a solicitar si por ejemplo ingresó mal la edad y /o
la inicial, esto se deberá validar al momento de grabar, por lo tanto se analizará el ingreso
de los datos una vez que hayan sido ingresados en su totalidad y optaremos por grabarlos
en el archivo de datos o bien en el archivo de errores según corresponda.
Aclaración: A pesar que en los ejemplos vistos hemos trabajado con un solo archivo,
muchos programas trabajan con varios archivos, por lo tanto un programa podrá tener
abiertos simultáneamente tantos archivos como sean necesarios.
Proponemos revisar los programas realizados en las evaluaciones del taller anterior e
identificar los archivos utilizados.
Quinto: Modularización de las operaciones
Como podemos observar en el ejemplo anterior hemos utilizado módulos (procedimientos o
funciones) para el desarrollo de las herramientas de manejo de los archivos: ABRIR, CERRAR,
LEER, GRABAR.
El objetivo de utilizar estas herramientas está dado en el hecho de modularizar, esto es no
utilizar las instrucciones de manejo de archivos directamente en los programas.
Cuáles son las ventajas de trabajar con esta modalidad:
1.
2.
3.
Si tenemos varios programas que utilizan el mismo archivo (es lo habitual)
podemos generar “librerías”, en el sentido del módulo I, en las cuales agrupamos el
diseño del registro y las cuatro operaciones básicas.
Así, cuando debamos modificar el diseño, o el tipo de acceso, simplemente lo
hacemos en un único archivo (nnnnn.h, nnnnn.cpp) y al compilar los programas
“importan” las modificaciones realizadas.
Si cambiamos de lenguaje de programación o de versión de C++ y las
instrucciones son incompatibles con las que tenemos desarrolladas, podremos
modificar únicamente en estas librerías.
Qué debemos tener en cuenta a la hora de modularizar y armar librerías:
1. Por cada archivo que utilicemos en nuestros programas debemos armar una librería
(nnnn.h, nnnn.cpp)
2. En el archivo de extensión “h” debemos incluir el diseño del regsitro (struct), y los
prototipos de las 4 operaciones básicas
3. En el archivo de extensión “cpp” debemos incluir la línea #include “nnnn.h”, y el
desarrollo de los prototipos descriptos en el archivo de extensión “h”.
4. Para definir el nombre de la estructura del registro debemos utilizar reglas nmotécnicas:
por ejemplo para el archivo “alumnos” podemos utilizar typedef struct recAlu {}
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 16
NSTITUTO de TECNOLOGÍA O. R. T.
Instituto Incorporado a la Enseñanza Oficial (A-763)
Analista de Sistemas de Computación
Taller de Computación II
5. Para definir el nombre de los procedimientos de archivos debemos utilizar nombres
nmotécnicos: por ejemplo para el archivo “alumnos”, el procedimiento leer es:
“leerAlu(….)
6. Los programas de aplicación deben utilizar los archivos a través de la implementación de
librerías, y de las herramientas correspondientes. Por lo tanto no debemos escribir:
fopen, fclose, fread, fwrite y feof en los programas de aplicación.
Actividad 3 - 5:
-
Realizar los cambios necesarios al programa recientemente explicado, para que utilice
librerías con los archivos, con el manejo de pantalla y con todo aquello que considere
que es de uso general.
.
ver 3.0 - Yatay 240 - Bs As - República Argentina
Pag. 17