Prácticas de C++ Practica Nº 10 I n f o r m át i c a I I F u n d am e n t o s d e P r o g r am ac i ó n Prof. Dr. Paul Bustamante INDICE 1.1 EJERCICIO 1: MI PRIMER FICHERO EN BINARIO.................................................................................. 1 1.2 EJERCICIO 2: LEYENDO MI PRIMER FICHERO EN BINARIO. ................................................................. 2 1.3 EJERCICIO 3: EJERCICIO COMPLETO DE LECTURA/ESCRITURA. .......................................................... 2 1.4 EJERCICIO 4: GRABANDO ESTRUCTURAS ........................................................................................... 3 Introducción. En esta práctica vamos a hacer ejercicios para escribir y/o leer ficheros en formato binario, esto quiere decir que las variables numéricas serán almacenadas “byte a byte”, por lo cual nuestros ficheros no se van a poder leer con cualquier editor de texto, hará falta otro programa que lea en binario, el cual también tendremos que hacerlo nosotros. Cuando trabajemos con “streams” binarios usaremos las funciones write y read. 1.1 Ejercicio 1: Mi primer fichero en Binario. En este ejercicio vamos a escribir ficheros en binario, esto quiere decir que no se podrán leer desde un editor de texto, ya que por ejemplo el número 1298.456 se puede representar en una variable tipo float que ocupa 4 bytes. Si este número lo escribo en formato texto, voy a ocupar 8 bytes, incluido el punto decimal; en cambio si escribo los 4 bytes que representan la variable, ocuparé la mitad. Y esto multiplicado por las muchas variables que se manejan en un programa, se ahorra bastante espacio en el disco. #include <fstream.h> #include <math.h> int main(int argc, char* argv[]) { float val, PI=(float)3.141592; fstream foutT("datos.txt",ios::out); //fichero Texto fstream foutB("datos.dat",ios::out|ios::binary); //fiche. Binario if (!foutT | !foutB) { cerr << "Error..." << endl; return -1; } // generar datos (una grafica del seno, 4 ciclos y amplitud 5v.) //en incrementos de PI/10 foutT.precision(5); foutT.setf(ios::fixed); for (float i=0;i<8*PI;i+=PI/10){ val = (float)(5.0*sin(i)); foutB.write((char*)&val,sizeof(float)); foutT << val << endl; } foutB.close(); //cierra fichero Binario foutT.close(); //cierra fichero Texto cout << "He terminado.."; return 0; } Practica Nº 10 Programación en C++ Pág. 2 Este programa genera dos ficheros: datos.txt y datos.dat. Si ves las propiedades de cada uno, verás que datos.dat ocupa menos de la mitad que datos.txt. Trata de ver estos ficheros con un editor de texto ¿qué ocurrirá? ¿podrás ver bien los datos en ambos ficheros? El fichero datos.dat ocupa menos espacio en el disco porque está escrito en formato binario, es decir que se han escrito los cuatro bytes de cada valor. Crea un proyecto Ejer1 y el fichero BinarioOut.cpp para que copies el código que te he dado. 1.2 Ejercicio 2: Leyendo mi primer fichero en Binario. Este ejercicio consiste en que debe hacer un programa para que lea del fichero datos.dat (del ejercicio anterior) y saque por consola los valores obtenidos. Para ello puede abrir el fichero de la siguiente forma: ifstream finB("datos.dat",ios::in | ios::binary); //fiche. Binario Al declarar streams de las clases ofstream o ifstream y abrirlos en modo binario, tenemos que añadir el valor ios::out e ios::in, respectivamente, al valor ios::binary. Esto es necesario porque los valores por defecto para el modo son ios::out e ios:in, también respectivamente, pero al añadir el flag ios::binary, el valor por defecto no se tiene en cuenta. Para leer puede usar la función Read(..) y la función Eof() para detectar cuando ha llegado al final del fichero. Puede mirar también los apuntes de clase para que le ayuden a hacerlo. 1.3 Ejercicio 3: Ejercicio completo de lectura/escritura. Este es un ejercicio completo sobre lectura y escritura de ficheros binarios. El ejercicio consiste en hacer un programa con el Menu que se muestra en la figura de la derecha, y cuyas opciones se describen a continuación: Opción1 Como puede ver, el ejercicio básicamente consiste en pedir datos al usuario y calcular la media aritmética de dichos datos. Hasta aquí es lo que hemos venido haciendo habitualmente y, supongo, que no tendréis dificultad alguna en hacerlo. Opción2 Lo más interesante es que una vez que hemos introducido los datos por teclado, éstos pueden ser grabados en el disco, en un fichero (cuyo nombre nos lo debe pedir el programa) en formato binario. Informática II – Fundamentos de Programación - Tecnun Practica Nº 10 Programación en C++ Pág. 3 Opción3 También debe existir la posibilidad de que al iniciar el programa, el usuario pueda cargar los datos desde un fichero que está en el disco. El programa debe verificar que exista, sino, debe mostrar un aviso. Opción4 Mediante esta opción, el usuario podrá ver los datos que hay en las variables del programa, ya sea porque se han cargado desde el disco, como los datos introducidos por teclado. Opción5 Esta opción debe permitir que el usuario pueda cambiar sólo el valor de un dato, en una determinada posición. Opción6 Mediante esta opción, el usuario podrá calcular la media de los datos que hay en las variables del programa, ya sea porque se han cargado desde el disco, como los datos introducidos por teclado. A continuación se muestra la arquitectura básica de main(): void main() { int num,opc=0; double *dat=NULL; while(1){ opc=menu(); switch(opc){ case 1: case 2: case 3: case 4: case 6: case 7: } } } dat=PideDatos(dat,num); break; GrabaDatos(dat,num); break; dat=CargarDatos(dat,num); break; PrtDatos(dat,num); break; Media(dat,num); break; if (dat!=NULL) delete [] dat; return; //salir 1.4 Ejercicio 4: Grabando estructuras Hemos dicho que cuando trabajemos con “streams” binarios usaremos las funciones write y read. En el caso de este ejercicio, estas funciones nos permiten escribir y leer estructuras completas a los ficheros de datos. Véase la siguiente estructura, la cual usaremos para grabar y leer datos del disco: struct Registro { char nombre[16]; int edad; float altura; }; Para saber el tamaño en bytes de una estructura, se puede usar la siguiente sentencia: Informática II – Fundamentos de Programación - Tecnun Practica Nº 10 Programación en C++ Pág. 4 int len=sizeof(Registro); Debe hacer un programa que permita pedir los datos de una persona para guardarlos en un fichero binario. Para hacerlo debe usar la estructura Registro, ya que es una forma más fácil de almacenar información en el disco. A continuación se muestra el código para escribir los datos: struct Registro { char nombre[16]; int edad; float altura; }; void main() { Registro reg1; fstream fout("registro.dat",ios::out|ios::binary); while(1){ cout << "nombre(x-salir):"; cin >> reg1.nombre; if (reg1.nombre[0]=='x') break; cout << "edad:"; cin >> reg1.edad; cout << "altura:"; cin >> reg1.altura; } fout.write((char*)&reg1,sizeof(Registro)); } cout << "datos grabados OK.."<<endl; fout.close(); //escribir Como segunda parte del ejercicio, ahora debe modificar el programa para que permita leer los datos escritos en el apartado anterior, usando la misma estructura Registro. Informática II – Fundamentos de Programación - Tecnun