Prácticas de C++ Practica Nº 14 Informática II Fundamentos de Programación Prof. Dr.Paul Bustamante Practica Nº 14 Programación en C++ Pág. 2 ÍNDICE ÍNDICE..................................................................................................................................................................... 2 1. Introducción................................................................................................................................................. 2 1.1 Ejercicio 1: Grabando a disco ficheros de texto con formatos. ............................................................ 2 1.2 Ejercicio 2: Agregando más cosas al fichero. ...................................................................................... 3 1.3 Ejercicio 3: Leyendo mis ficheros........................................................................................................ 3 1.4 Ejercicio 4: Lectura y escritura de ficheros Binarios. .......................................................................... 3 1.5 Ejercicio 5: Grabando datos de una gráfica en formato binario. .......................................................... 4 1.6 Ejercicio 6: Escribiendo y Leyendo Objetos de disco.......................................................................... 5 1. Introducción. Hemos llegado al final de la asignatura y no podemos terminar el curso sin poder escribir todos los datos de nuestros programas en un fichero. En esta práctica va a hacer ejercicios de formatos (para escribir en ficheros de texto, leerlos con cualquier editor de texto, ejemplo Notepad) y escribir y leer objetos a disco, utilizando el formato binario. 1.1 Ejercicio 1: Grabando a disco ficheros de texto con formatos. Este ejercicio consiste en hacer un programa que vaya pidiendo al usuario un nombre y la edad para ir generando un fichero que los escriba con el siguiente formato: Rafael...........38 Juan.............22 Ricardo..........25 Carla.............5 El nombre del fichero en el que desea guardar los datos también se le pide al usuario. A continuación se muestra el código del programa. Debes crear el proyecto Ejer1 y el fichero DiscoOut.cpp, en el que vas a copiar el siguiente código: // DiscoOut.cpp // #include <fstream.h> #include <string.h> int main(int argc, char* argv[]) { char nombre[80],filename[80]; int edad; cout << "Nombre del fichero a grabar:"; cin >> filename; ofstream fout(filename); //abrir el fichero if (!fout) { cerr << "Error.."; return -1; } fout.fill('.'); while(true){ cout << "Nombre (salir-termina):"; cin >> nombre; if ( strcmp(nombre,"salir") == 0) break; cout << "Edad:"; cin >> edad; fout.width(15); fout.setf(ios::left); fout << nombre; //escribe datos a disco fout.unsetf(ios::left); fout.width(4); fout << edad << endl; //escribe datos a disco } fout.close(); Informática II – Fundamentos de Programación - Tecnun Practica Nº 14 Programación en C++ Pág. 3 cout << "Datos grabados en: " << filename << endl; } return 0; El fichero generado puedes abrirlo con el Notepad o con el mismo Visual Studio y verificar que obtienes los datos con el formato establecido. 1.2 Ejercicio 2: Agregando más cosas al fichero. Modificar el programa anterior para que pida además del nombre y de la edad, la dirección y el número de teléfono y que escriba en el fichero con el siguiente formato: Carla.............5..Aizkorri 84....................943215678 Juan.............28..Manuel Lardizabal 15...........943212800 Reservar para la dirección 30 caracteres (en la escritura, no en la variable) y para el teléfono 10 caracteres. Usar como variable para el teléfono un long. Para pedir la dirección, no se puede hacer con cin, ya que éste no acepta espacios. Hay que utilizar la función getline de cin: cin.getline(char *,int n): char dir[80]; long telefono; . . . cout << "Direccion:"; char ch; //sacar el enter cin.get(ch); cin.getline(dir,80); . . . Antes de usar getline, hay que usar la función get para atrapar el enter que se queda en el buffer de entrada. Puedes compilar el programa y crear tus nuevos ficheros, los cuales puedes ver con un editor de texto. 1.3 Ejercicio 3: Leyendo mis ficheros. Este ejercicio consiste en crear un programa que te permita leer un fichero del disco, cuyo nombre lo debes pedir al usuario, y sacarlo por la consola. Para esto debes usar la función getline(..), para que puedas leer una línea completa. char tmp[120]; char filename[80]; cout << "Nombre del fichero a leer:"; cin >> filename; ifstream fin(filename,ios::in|ios::nocreate);//abrir fichero if (!fin) { cerr << "Error.."; return -1; } while(true) { fin.getline(tmp,120); if ( fin.eof() ) break; //termina la lectura cout << tmp << endl; //escribir en la consola } fin.close(); Crea un proyecto Ejer3 y el fichero DiscoIn.cpp, en el cual copiarás el código anterior. Para ejecutarlo, puedes darle como nombre del fichero a leer el mismo DiscoIn.cpp. 1.4 Ejercicio 4: Lectura y escritura de ficheros Binarios. En los ejercicios anteriores hemos escrito y leído de ficheros de texto. En este ejercicio vamos a escribir ficheros en binario, esto quiere decir que no se podrán leer desde un editor de texto, Informática II – Fundamentos de Programación - Tecnun Practica Nº 14 Programación en C++ Pág. 4 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(6); 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; } 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 Ejer4 y el fichero BinarioOut.cpp para que copies el código que te he dado. Ahora tú debes hacer un programa para que lea del fichero datos.dat y saque por consola los valores obtenidos. Para ello puedes abrir el fichero de la siguiente forma: fstream finB("datos.dat",ios::in|ios::binary); //fichero Binario Para leer puedes usar la función read(..) y la función eof() para detectar cuando has llegado al final del fichero. Puedes mirar los apuntes de clase para que te ayuden a hacerlo. 1.5 Ejercicio 5: Grabando datos de una gráfica en formato binario. El siguiente ejercicio consiste en hacer un programa que pida datos de Temperatura a lo largo del día (1 por cada hora) y que sea capaz de calcular la media de dichos datos y grabarlos al disco en formato binario, de tal forma que se puedan volver a leer y hacer el cálculo de la media nuevamente sin necesidad de volver a introducir los datos. Informática II – Fundamentos de Programación - Tecnun Practica Nº 14 Programación en C++ Pág. 5 1.6 Ejercicio 6: Escribiendo y Leyendo Objetos de disco Este ejercicio consiste en hacer un programa que permita grabar los objetos tipo Fecha. Para ello, hemos creado un array estático de objetos tipo Fecha, con lo cual no es necesario crear los objetos con el operador new. A continuación podemos ver el código: //Escribir y leer objetos #include <iostream.h> #include <fstream.h> #include <iomanip.h> class Fecha{ short dia,mes,anyo; public: Fecha(short d=1, short m=1, short a=99): dia(d),mes(m),anyo(a){ ; } friend ostream &operator<<(ostream& co, Fecha &f){ co.fill('0'); co <<setw(2)<<f.dia <<"/"<<setw(2)<<f.mes<<"/"<<f.anyo; return co; } friend fstream& operator<<( fstream& fo, Fecha &f){ fo.write( (char*)&f, sizeof(Fecha)); return fo; } friend fstream& operator>>( fstream &fi, Fecha &f){ fi.read((char*)&f,sizeof(Fecha)); return fi; } }; #define NUM 30 void Leer(char *); void main() { char name[80]; Fecha fechas[NUM]; //array estático de NUM objetos int num=0,opc; cout << "Leer(1) o Escribir(2):"; cin >> opc; . . . //pedir nombre del fichero if (opc==1) { Leer(name); return; } while(true){ int d,m,a; cout << "Introd. Fecha (d m a):"; cin >> d >> m >> a; if (d==-1) break; fechas[num++] = Fecha(d,m,a); //asignar objeto Anónimo if (num >= NUM) break; } for (int i=0;i<num;i++) cout << fechas[i] << endl; //escribir a disco fstream fout(name , ios::app|ios::binary); //para agregar fechas for (int i=0;i<num;i++) fout << fechas[i]; fout.close(); } void Leer(char *name) { fstream fin("name,ios::in|ios::nocreate|ios::binary); if (!fin) { cerr << "Error"; return;} Fecha f; while(true){ fin >> f; if (fin.eof())break; cout << f << endl; } } Informática II – Fundamentos de Programación - Tecnun