/* Este programa ha sido realizado por Pablo Ruiz y Fernando Hueso en la asignatura: Técnicas informáticas, Prácticas de Laboratorio. 1º de Física, curso 2007-08. Nombre del Programa: Estaciones meteorológicas Propósito: Sistema de Gestión de los pluviómetros de las estaciones meteorológicas de la Comunidad Valenciana. */ //Errores detectados: si introduces numeros mayores que el límite del tipo de dato. //Si el fichero no sigue la estructuración lógica. //Si en lugar de un caracter introduces una cadena (error controlado hasta cadena de TAM caracteres) // o en lugar de un numero una cadena. En algunos casos entra en un bucle infinito //El resto de ocurrencias se han controlado. #include #include #include using namespace std; //Constantes #define LIT 12 #define TAM 100//Nº maximo de municipios. //Estructuras struct estacion { unsigned short cod; string mun; float litros[LIT]; }; //PROTOTIPOS DE FUNCIONES int main(); //inicialización void inicio(string &fich,unsigned short &num,unsigned short &num2,struct estacion x[TAM]); unsigned short volcar (ifstream &f, string fich, struct estacion x[TAM]); //recurrentes char menu(char &op); unsigned short codigo(string nombre); int buscamu(struct estacion x[TAM], unsigned short num, string mun); void error(); //a void buscar(struct estacion x[TAM], unsigned short num); //b void escribir (struct estacion x[TAM], unsigned short num); void mostrarmu (int pos, struct estacion x[TAM]); void mostrarlit (float v[LIT]); //c void insertar (string mun,struct estacion x[TAM], unsigned short &num2); void ins(struct estacion x[TAM],unsigned short &num2); //d void guardar (string fich, struct estacion x[TAM], unsigned short &num, unsigned short num2); //e,f,g void munprov (struct estacion x[TAM], unsigned short num); void horas (struct estacion x[TAM], unsigned short num); void comval (struct estacion x[TAM], unsigned short num); void iwal (float a, float &b); void comparar (float v, float &max, float &min, float &med); //h void modificar (struct estacion x[TAM],unsigned short num, string fich); void reemplazar (struct estacion x[TAM],unsigned short num, string fich); //j void salir(string fich,struct estacion x[TAM],unsigned short &num,unsigned short num2); /*Función: Volcar fichero Descripción de la función: Volcar fichero a un vector de estructuras separado por campos Parámetros: fichero de lectura f por referencia, nombre del fichero fich y vector con las estructuras. Detalles: devuelve error si no encuentra el fichero y no hace nada más, si lo encuentra lo rellena hasta fin de fichero, y devuelve i, que es el nº de elementos que se han rellenado en la estructura. Esto será utilizado para saber hasta donde leer en el array. Si hay error, devuelve 0 (o si el fichero está vacío). Por tanto no realizará acciones en otras operaciones.*/ unsigned short volcar (ifstream &f, string fich, struct estacion x[TAM]) { unsigned short i=0, j; f.open(fich.c_str()); if (!f) { cout << "Error.\n"; } else { for (i=0; f>>x[i].cod;i++)//el fichero no acaba con un salto de linea, //pero como comprobamos con f>>x[i].cod, no hay problema y no entra en el bucle. { f.ignore();//ignora el tabulador getline(f,x[i].mun); for (j=0; j>x[i].litros[j]; } } f.close(); } return i; } /*Función: Escribir en pantalla Descripción de la función: Muestra las estructuras guardadas en el vector de forma ordenada y tabulada. Parámetros: array de estructuras (Automáticamente por referencia), num: numero hasta donde leer el array. (cuántas estaciones hay guardadas) Detalles: es un procedimiento. Llama a la función base de escribir un municipio. No tiene en cuenta las modificaciones si no se ha actualizado antes.*/ void escribir (struct estacion x[TAM], unsigned short num) { int i; cout << endl; for (i=0; i> x[num2].litros[i]; } cin.ignore(TAM,'\n');//para que no se acumule el error posteriormente si alguien no mete //datos de tipo float. num2=num2+1; cout << "Datos cargados correctamente.\n"; } } /*Función: Reconoce código Descripción de la función: Dado el nombre de la provincia le asigna el código correspondiente. Parámetros: Nombre (string) de la provincia Devuelve: con return el código de provincia, un cero en caso de que no exista la provincia dada. Detalles: El string que le pasan tiene que ser idéntico, no puede haber espacios al final ni comas ni nada por el estilo.*/ unsigned short codigo(string nombre) { if (nombre=="Valencia") { return 46; } else { if (nombre=="Alicante") { return 3; } else { if (nombre=="Castellon") { return 12; } else { return 0; } } } } /*Función: Mensaje de error Descripción de la función: Muestra un mensaje de error base utilizado en los menús cuando se introduce un dato no permitido. Detalles: Procedimiento, no tiene parámetros ni devuelve nada. Sólo saca el mensaje.*/ void error() { cout << "Error, se reinicia el menu.\n"; } /*Función: Comparación de valores Descripción de la función: Va comparando valores y encuentra maximos y minimos. Ademas, calcula la suma de valores, para la media. Parametros.*/ void comparar (float v, float &max, float &min, float &med) { if (v>max) { max=v; } else { if (v> op; cin.ignore(TAM,'\n');//controla el error si metes una cadena hasta de TAM caracteres. return op; } /*Función: Inicializar programa Descripción de la función: Carga el nombre del fichero en una variable que se utilizará en adelante. (No la pide, sino que se escribe en el código, para que cuando se quiera cambiar desde el código, sólo haya que cambiar en este punto el nombre.) Además carga los datos llamando a la función volcar, y establece el número relleno de posiciones del vector de estructuras. Parámetros: por referencia el string fich con el nombre, los numeros num y num2 por referencia, y el array de estructuras. Detalles: num=num2 para que cuando actualice no haga nada, pues no se ha modificado nada. Si se modifica algo num2 será mayor y guardará tantas nuevas estaciones como num2-num1. */ void inicio(string &fich,unsigned short &num,unsigned short &num2,struct estacion x[TAM]) { ifstream f; fich="precipitaciones.txt"; num=volcar(f,fich, x); num2=num; } /*Función: case a Descripción de la función: Busca un municipio y llama a la función para que muestra la observación Parámetros: Vector de estructuras x Detalles: Filtro de errores si buscas un municipio no existente (buscamu devuelve -1 y saca mensaje de error. En caso de que exista llama a mostrarmu que muestra la observación. */ void buscar(struct estacion x[TAM], unsigned short num) { int pos; string mun; cout << "Introduce el nombre del municipio exactamente, mayuscula la primera, y sin acentos.\n"; getline(cin,mun); if ((pos=buscamu(x, num, mun))==-1) { error(); cout << "Municipio no existente.\n"; cout << "Comprueba que lo has escrito correctamente distinguiendo"; cout << " mayusculas de minusculas.\n"; } else { mostrarmu(pos,x); } } /*Función: case j Descripción de la función: Salir y preguntar antes si debe guardar Parámetros: Vector de estructuras x, nombre de fichero fich, num y num2 que marcan posición original y modificada (cuántas estaciones se han añadido), fichero de escritura que se utiliza en el caso de que se quiera guardar. Detalles: Finaliza el programa. */ void salir(string fich,struct estacion x[TAM],unsigned short &num,unsigned short num2) { char ch; cout << "Deseas guardar los datos? Pulsa 'S' para guardarlos, otra letra para salir.\n"; cout << "La S es mayuscula, tenlo en cuenta o perderas los datos.\n"; cin >> ch; if (ch=='S') { guardar (fich, x, num, num2); } cout << "\nEl programa ha finalizado.\n"; cout << "Consulte datos en su fichero " << fich << ".\n"; } /*Función: case c Descripción de la función: Insertar un municipio a continuación del vector (en memoria) Parámetros: Vector de estructuras x, y num2 (num no hace falta!) Detalles: error si el municipio ya existe (no se puede cambiar los datos de una observación) */ void ins(struct estacion x[TAM],unsigned short &num2) { string mun; cout << "Dime el nombre del municipio exactamente, primera letra en mayuscula"; cout << " y todas sin acentos.\n"; getline(cin,mun); if (buscamu(x,num2,mun)!=-1) { error(); cout << "Municipio ya existente.\n"; cout << "Puede ser que lo acabes de introducir y que no hayas actualizado, "; cout << "por lo que no te aparece al pulsar b.\n"; } else { insertar (mun, x, num2); cout << "Si quieres que calcule bien el resto de opciones"; cout << " tienes que pulsar la opcion d para actualizar los datos.\n"; } } /*Función: case h Descripción de la función: Modificar los litros recogidos en un municipio Parámetros: Array de estaciones, numero relleno, nombre del fichero string fich Detalles: Pide el nombre del municipio, lo busca en el vector y a continuación guarda en el campo litros lo que vaya introduciendo el usuario. Luego pregunta si desea guardarlo. En caso afirmativo llama a una función para que reescriba el fichero entero hasta num. En caso negativo vuelve al menu. */ void modificar (struct estacion x[TAM],unsigned short num, string fich) { string mun; int pos; unsigned short i; char ch; cout << "La modificacion se actualiza automaticamente, es decir, "; cout << "no hace falta que pulses la opcion d para que se guarde en el fichero.\n"; cout << "El programa lo hace directamente.\n"; cout << "Introduce ahora el nombre del municipio: "; getline (cin,mun); if ((pos=buscamu(x,num,mun))==-1) { error(); cout << "Municipio no existente. Pulsa la opcion c. para insertar una nueva estacion.\n"; } else { cout << "Introduce ahora los litros en cada una de las ultimas doce horas.\n"; for (i=0;i> x[pos].litros[i]; } cout << "Deseas actualizar esta modificacion en tu fichero?"; cout << " Pulsa 'S' para guardar, otra letra"; cout << " en caso contrario.\nLa S es mayuscula, tenlo en cuenta o"; cout << " perderas los datos introducidos.\n"; cin >> ch; cin.ignore(TAM,'\n'); if (ch=='S') { reemplazar(x,num,fich); } else { cout << "Datos no cargados. Se reinicia el menu.\n"; } } } /*Función: Reescribir fichero Descripción de la función: Reescribe el fichero hasta num con la modificacion de litros recogidos hecha. Parámetros: Vector de estructuras x, num y nombre del fichero Detalles: no actualiza las estaciones añadidas en c. */ void reemplazar (struct estacion x[TAM],unsigned short num, string fich) { unsigned short i, j; ofstream g; g.open(fich.c_str()); if (!g) { cout << "Error.\n"; } else { for (i=0; i