IP 2013 c2, Practica 11: Uso de Archivos en C++

Anuncio
UNIVERSIDAD DON BOSCO
FACULTAD DE ESTUDIOS TECNOLOGICOS
ESCUELA DE COMPUTACION
GUIA DE LABORATORIO Nº 11
CICLO
02-2013
Nombre de la práctica: Uso de archivos en C++
Lugar de ejecución: Laboratorio de Informática
Tiempo estimado: 2:30 horas
Materia: Introducción a la Programación
I. Objetivos
Que el estudiante sea capaz de:
•
•
•
•
•
Acceder a archivos de texto plano (.txt) con las funciones de la librería fstream.h de C++
Manejar las operaciones básicas con los flujos entrada (ifstream) y de salida (ofstream) de archivos
Utilizar las funciones de manejo de archivos disponibles en librería fstream.h
Escribir y leer datos de archivos de texto en C++
Utilizar funciones de conversión de tipos de datos proporcionados por librería stdlib.h
II. Introducción
Uso de archivos en C++
Un archivo es un conjunto sistematizado de información homogénea. Consta de una colección de información,
estructurada en unidades de acceso llamada artículos o registros.
Archivos y streams
C++ ve a cualquier archivo simplemente como una secuencia de bytes.
Un archivo finaliza ya sea con una marca de end-of-file (eof) o en un byte determinado (tamaño del archivo) en
una estructura de datos administrada por el sistema operativo (como un archivo en un directorio).
Cuando un archivo se abre, se instancia un objeto archivo del tipo adecuado y un stream (también llamado
nombre de archivo lógico) es asociado con este objeto.
Para realizar estas acciones en C++ deben incluirse los archivos <iostream> y <fstream>
___________________________________________________________________________________________
1
Jerarquía de clases stream
Apertura de archivos
Se define una variable (por ejemplo a r c h i v o ) para administrar el flujo de acceso al archivo (ofstream), por ej.
ofstream archivo;
Luego se invoca al método open con el parámetro apropiado según la siguiente sintaxis:
archivo.open ("ejemplo.txt", ios::out | ios::app | ios::binary);
Tipo acceso
ios::in
Descripción
Abrir archivo para lectura
ios::out
Abrir archivo para escritura
ios::ate
Posición inicial: fin del archivo
ios::app
Cada salida se agrega al final del archivo
ios::trunc
Si el archivo ya existe se borra su contenido
ios::binary
Modo binario
___________________________________________________________________________________________
2
Por ejemplo:
ofstream archivo ("ejemplo.bin", ios::out | ios::app | ios::binary);
Funciones de archivos
Archivo.close();
Se encarga de vaciar los buffers que usa el archivo y cerrar acceso al archivo.
Función e o f ( )
Para conocer si se ha llegado al final del archivo al leerlo.
Opciones de estado
Permiten conocer el estado de los flujos de datos del contenido de un archivo.
bad(): Retorna true si ocurre una falla en las operaciones de lectura o escritura. Por ejemplo en caso de que
tratemos de escribir en un archivo que no está abierto para escritura.
fail(): Retorna true en los mismos casos que bad() y además en caso de que ocurra un error de formato, como
tratar de leer un número entero y obtener una letra.
eof(): Retorna true si el archivo abierto ha llegado a su fin.
good(): Es el más genérico. Retorna false en los mismos casos en los que al llamar a las funciones previas se
hubiera obtenido true.
Ejemplos de operaciones sobre archivos
Escribir en un archivo de texto
// escribiendo en un archivo de texto
#include <iostream>
#include <fstream>
using namespace std;
main() {
ofstream ejemplo("ejemplo.txt");
// Crea un archivo de salida
if(ejemplo.is_open()){
//Comprueba si el archivo esta abierto
// Enviamos dos cadenas al archivo de salida:
ejemplo<<"Esto es una linea.\n";
ejemplo<<"Esto es otra linea.\n";
ejemplo.close(); // Cierra el acceso al archivo
ejemplo.clear();
//limpia buffer lectura del flujo del archivo
}
}
Leer contenido de un archivo de texto:
// leer un archivo de texto
#include <iostream>
#include <fstream>
___________________________________________________________________________________________
3
using namespace std;
int main(){
char buffer[256];
ifstream ejemplo("ejemplo.txt");
if(!ejemplo.is_open()){
cout<<"Error al abrir el archivo";
exit(1);
}
while(!ejemplo.eof()){
ejemplo.getline(buffer,100);
cout<<buffer<<endl;
}
system("pause");
return 0;
}
Ejemplo de resultado del código anterior:
Funciones de conversión de tipos de datos
Gracias al registro de datos dentro de archivos de texto, se logra almacenar diferente tipo de información en
los mismos, por ej.: fechas, nombres, descripciones, cantidades, distancias, etc.
Como complemento a esta interacción con información almacenada en archivos, se necesita conocer un
conjunto de funciones definidas en la librería stdlib.h, que permiten convertir texto en representaciones
numéricas y viceversa. A continuación se describen las más utilizadas.
Función itoa( )
char *itoa(int value, char * str, int Base);
Convierte un valor entero (value) a una cadena caracteres (str), indicando opcionalmente a la base (Base) del
sistema numérico en la que se expresara la respuesta, ej.
int n;
char buffer[33];
cout<<"ingrese un numero entero: "; cin>>n;
itoa (n,buffer,10);
cout<<"decimal es "<<buffer;
itoa (n,buffer,16);
cout<<endl<<"hexadecimal sera "<<buffer;
itoa (n,buffer); //si ignora la base, asume que la misma es base 10
cout<<"decimal es "<<buffer;
___________________________________________________________________________________________
4
Una salida del código anterior seria:
ingrese un numero entero: 1750
decimal es 1750
hexadecimal sera 6d6
decimal es 11011010110
Function atoi
int atoi (const char * str);
Retorna la conversión a valor entero de una cadena de caracteres (s t r )
La cadena puede contener caracteres adicionales después de los que forman el número entero, que serian
ignorados y no tienen ningún efecto sobre el comportamiento de esta función.
Si el inicio de la secuencia de caracteres en str (que no sean espacios en blanco) no representan un número
entero válido, o si no existe tal secuencia, ya sea porque str está vacío o sólo contiene espacios en blanco, la
conversión no se realiza y la función devuelve cero (0).
Ejemplo:
int i;
char buffer[256];
cout<<"Ingrese un numero entero: ";
cin.getline(buffer, 256); //se captura entero como cadena de caracteres
i = atoi (buffer); //convierte cadena buffer a tipo de dato entero
i= i * 2;
cout<<"\nEl doble del valor ingresado fue de "<< i;
Una salida del código anterior podría ser:
Ingrese un numero entero: 73
El doble del valor ingresado fue de 146
Function atof ( )
double atof (const char* str);
Retorna un valor double de la conversión de un string.
Comienza de izquierda a derecha, buscando la secuencia valida de una representación numérica. En caso de un
carácter no valido, ignora la cadena restante.
Ejemplo de uso:
double n,m;
double pi=3.1415926535;
char buffer[256];
cout<<"Ingrese valor de grados sexagesimales: ";
cin.getline(buffer,256);
n = atof (buffer); //convierte cadena buffer a valor double
m = sin (n*pi/180); //convierte numericamente a grados radianes
cout<<"\nValor de "<<n<<" grados sexagesimales en radianes son "<< m;
___________________________________________________________________________________________
5
Ejemplo de salida del código anterior:
Ingrese valor de grados sexagesimales: 45
Valor de 45 grados sexagesimales en radianes son 0.707101
III. Requerimientos
Nº
1
2
3
Cantidad
1
1
1
Descripción
Compilador Dev-C++
Guía de Laboratorio #11 de Introducción a la Programación
Memoria USB
IV. Procedimiento
1.
Preparar una carpeta denominada IPguia11proc_CARNET, en el cual guardara cada uno de los cpp’s del
procedimiento y de los problemas a resolver.
Creando un archivo de texto plano (.txt)
2.
Crear un nuevo archivo de código fuente denominado guia11Ejemplo1 y digite el siguiente código:
#include<iostream>
using namespace std;
//biblioteca de C++ que proporciona “funciones” y operadores
//para el manejo de archivos
#include<fstream>
#include<stdlib.h>
main(){
ofstream archivo; // crea un objeto de la clase ofstream
char nom[25];//nombre a solicitar a usuario
cout<<"\tDemostracion acceso a un archivo de texto\n";
//Abre el archivo en forma de escritura (ios::out)
archivo.open("agenda.txt",ios::out);
//comprueba si archivo fallo al querer crearlo/abrirlo
if (!archivo){
cout<<"No se puede abrir el archivo" <<endl;
}else{
cout<<"Acceso correcto para escritura del archivo\n";
cout<<"Escriba 1er nombre a registrar en archivo:";
cin.getline(nom,25);
//escribe nombre en nuevo archivo
archivo<< "1er nombre: " << nom <<endl;
cout<<"Ahora escriba 2do nombre:";
cin.getline(nom,25);
//escribe nombre en nuevo archivo
archivo<< "2do nombre: " << nom <<endl;
___________________________________________________________________________________________
6
archivo.close(); //cierra el manejador archivo
cout<<"!!!!Los datos fueron agregados!!!"<<endl;
}
system("pause");
}//fin main
3.
Ejecute el programa anterior. Observe que la aplicación le indica que se ha logrado acceso al archivo para
escritura.
Por ser la 1er vez que ejecuta el programa, ofstream crea el archivo agenda.txt.
Minimice la ventana del compilador y observe contenido de su carpeta de trabajo. Se ha creado el archivo
en la misma carpeta donde se ha generado el .exe del cod.fuente de C++ actual.
Ingrese al archivo de texto agenda.txt para confirmar el contenido del archivo y cierre la ventana del editor
de texto
4.
Vuelva a ejecutar el programa y este le solicita nuevamente 2 nombres para escribir en archivo.
Abra nuevamente el archivo agenda.txt y compare su contenido actual con el de la 1er ejecución.
¿El contenido es de igual contenido o diferente?
5.
6.
Cerrar ventana del archivo agenda.txt y retornar al editor de C++. Cambia el nombre del archivo
“ a g e n d a . t x t ” por el de “ c : \ a g e n d a . t x t ” , para intentar crear el archivo de texto en la raíz del
sistema de archivos del disco duro.
Ejecutar de nuevo el programa y analice el resultado
7.
Retorne al cod.fuente del programa y restaure el nombre del archivo a crear como “ a g e n d a . t x t ” .
Además, reemplazar el parámetro resaltado i o s : : o u t por el del Modo agregar archivo (i o s : a p p ).
8.
9.
Ejecutar nuevamente el programa e indicar 2 nuevos nombres.
Retorne de nuevo al contenido del archivo agenda.txt y compare los resultados con las ejecuciones
anteriores.
Accediendo al contenido de un archivo de texto plano (.txt)
10. Guardar los cambios del archivo cpp actual y hacer una copia del mismo bajo el nombre guia11Ejemplo2.
De este nuevo cpp, borre todo el contenido de la función main, excepto la última función system(“pause”).
Ahora hará las pruebas de acceso a un archivo en modo Lectura, para obtener la información almacenada
en un archivo de texto ya existente.
11. Digite el siguiente código entre las llaves { } de main del cpp guia11Ejemplo2:
___________________________________________________________________________________________
7
ifstream archivo2;//variable para acceso de lectura a un archivo
char nombrearchivo[50]; //nom archivo a leer, dado por usuario
char lineatexto[100];//una linea texto copiada desde archivo a leer
int cl=0; //contador lineas leidas de archivo
cout<<"Indique nombre de archivo a acceder para lectura: ";
cin.getline(nombrearchivo,50);
//intenta abrir archivo nombrearchivo para lectura
archivo2.open(nombrearchivo,ios::in);
if(!archivo2){
cout<<"-> Error, archivo imposible de abrir\n";
}else{
cout<<"-> Acceso exitoso para lectura de archivo "<<
nombrearchivo<<"\nSu contenido lineaxlinea:\n";
//Comienza proceso lectura del archivo
//repetira lectura solo cuando no se alcance final contenido
while(!archivo2.eof()){
archivo2>>lineatexto;
cl++;
cout<<cl<<":\t"<<lineatexto<<endl;
}//fin while
cout<<endl;
archivo2.close();//cierra acceso archivo de lectura
}//fin if inicial
12. Guardar los cambios y compile el programa. Ante la solicitud del nombre del archivo, digitar miagenda.txt.
El programa indicara que el archivo de no pudo abrir.
13. Repita el paso anterior, pero digite el nombre del archivo de texto ya existente (agenda.txt)
Del resultado devuelto, ¿Qué es lo que realmente esta leyéndose del archivo con la línea de código
resaltada a r c h i v o 2 > > l i n e a t e x t o ?
14. Comente la línea resaltada del paso anterior e inserte en su lugar este comando:
archivo2.getline(lineatexto,100);
15. Ejecute de nuevo el programa para leer contenido de archivo agenda.txt. ¿Funciono esta vez la lectura de
las líneas del archivo?, ¿Hay algún problema en el resultado visto en pantalla?
Almacenando/Recuperando información de aplicaciones hacia/desde archivo de texto plano (.txt)
16. Crear un nuevo archivo cpp, para guardarlo bajo el nombre guia11Ejemplo3. En este ejemplo, se permite
el ingreso de los datos de un total de n cuentas de ahorro, para luego ir agregándolos dato por dato hacia
un archivo de cuentas (llamado cliente.txt).
#include <iostream>
#include <fstream>
using namespace std;
main(){
//datos cuenta ahorro
___________________________________________________________________________________________
8
int cuenta;
char nombre[15];
char apellido[15];
double saldo;
int n,i;
cout<<"Aplicacion para la creacion de registros bancarios\n\n";
//ofstream abre el archivo en forma de escritura
// ios::app agrega los datos al final del archivo
ofstream archivoclientessalida("cliente.txt", ios::app);
//Finaliza programa si no se puede crear el archivo
if (!archivoclientessalida){
cout<<"No se puede abrir el archivo" <<endl;
exit(1);//Finaliza main, sin ejecutar resto del codigo
}
cout<<endl<<"Digite el numero de clientes a ingresar: ";
cin>>n;
i=1;//inicia con empleado 1
//Lee cuenta, nombre y saldo con cin
while (i<=n) {
cout<<"\n\n--> Datos de Cuenta (#"<<i<<"):\n";
cout<<"\nNumero de cuenta ??\t";cin>>cuenta;
cout<<endl<<"Nombres ??\t";
fflush(stdin); cin.getline(nombre,15);
cout<<endl<<"Apellidos ??\t";
fflush(stdin); cin.getline(apellido,15);
cout<<endl<<"Saldo inicial($) ??\t ";cin>>saldo;
//Escribe variables anteriores en el archivo de salida
archivoclientessalida<<cuenta<<endl<<
nombre<<endl<<apellido<<endl<<saldo<<endl;
i++;//proximo empleado a registrar
} //fin de while i
//cierra acceso archivo de escritura
archivoclientessalida.close();
cout<<"\nSE TERMINO DE AGREGAR DATOS AL ARCHIVO\n";
system("pause");
}//fin main
17. Compilar y ejecutar el programa anterior. Ingresar un total de 2 cuentas bancarias y luego ingresar los
respectivos datos de c/u. Al finalizar el programa, localizar archivo cuentas.txt en la carpeta de trabajo y
revisar su contenido
18. Repetir el paso anterior, pero con datos de nuevas cuentas bancarias. Después revisar nuevamente el
archivo de texto cuentas.txt y confirmar que la información se va acumulando al final.
19. Crear un nuevo archivo cpp, para guardarlo bajo el nombre guia11Ejemplo4. En este último ejemplo, se
recupera la información sobre las cuentas bancarias registradas en el archivo de texto cuenta.txt (creadas
con el programa del ejemplo anterior).
#include <iostream>
#include <fstream>
#include <iomanip>
using namespace std;
___________________________________________________________________________________________
9
#include <conio.h>
main(){
//datos de una cuenta ahorro
char linea[10];
int cuenta;
char nombres[25];
char apellidos[25];
double saldo;
// ifstream abre el archivo en modo -lectura
ifstream archivoclientesentrada("cliente.txt",ios::in);
//sale del programa si ifstream no puede abrir el archivo
if (!archivoclientesentrada)
cout<<"no se puede abrir el archivo" <<endl;
else{
cout<<"\tLISTA DE CUENTAS BANCARIAS REGISTRADAS\n\n";
cout.setf(ios::fixed);
cout.precision(2);
//prepara encabezado de tabla a mostrar
cout<<"#Cuenta"<<setw(17)<<"Nombre"<<setw(25)<<
"Apellido"<<setw(16)<<"Saldo($)"<<endl;
//
Lista cada registro en el archivo
//verifica que no ha llegado al final del archivo
while (!archivoclientesentrada.eof()){
/*se captura del archivo los datos, para ser almacenados
en las variables del programa*/
archivoclientesentrada.getline(linea,10);
cuenta=atoi(linea);//convierte cadena texto en valor entero (int)
if(cuenta==0) //ya no hay cuentas que mostrar
break;//finaliza while
archivoclientesentrada.getline(nombres,25);
archivoclientesentrada.getline(apellidos,25);
archivoclientesentrada.getline(linea,9);
saldo=atof(linea);//convierte cadena texto en valor float
//muestra resultados en pantalla
cout<<setw(5)<<cuenta<<setw(25)<<nombres<<setw(25)<<
apellidos<<setw(10)<<saldo<<endl;
}//fin de while
}//fin de if
archivoclientesentrada.close();
cout<<endl;
system("pause");
}//fin main
20. Compilar y ejecutar el programa. Confirmar que los datos mostrados en la consola son los mismos
almacenados en el archivo de texto cliente.txt.
___________________________________________________________________________________________
10
PROBLEMAS A RESOLVER:
Elabore el código fuente de C++ que solucionen a cada uno de los problemas a continuación:
Problema1.cpp
Crear un programa que pida el salario base de n empleados. Calcule el salario neto de c/empleado, tomando en
cuenta que se le descuenta el 3% de ISSS y $60 por un seguro contra accidentes.
Almacenar en un archivo de texto denominado planilla.txt a la siguiente información:
+ Información de cada uno de sus empleados: nombres, código (formado por las 2 letras iniciales de su 1er
nombre y las 2 letras iniciales de su 1er apellido), su salario base y salario neto.
+ Monto de la planilla a pagar, así como el sueldo neto promedio general
Importante:
Los registros deben ser almacenados en el archivo, ordenados por el 1er apellido de los empleados.
El contenido del archivo debe quedar en un formato listo para imprimir, simulando una “tabla” (evaluar
para ello al ejemplo guia11Ejemplo4)
___________________________________________________________________________________________
11
Descargar