// Programación en C++ para Ingenieros, Ed. Thomson Paraninfo, 2006 // Capitulo 6: Tipos Estructurados // Programa que dados el nombre, los apellidos y la edad // de los habitantes de un barrio, permite hacer consultas // por nombre, apellido o intervalo de edad. // Inclusión de bibliotecas #include <iostream> #include <string> using namespace std; // Definición de constantes const int N = 15; // Las palabras tienen un máximo de N caracteres const int M = 1000; // Hay un máximo de M vecinos // Definición de tipos typedef char tNombre[N+1]; struct tHabitante { tNombre nombre, apellido1, apellido2; int edad; }; typedef tHabitante tDatos[M]; // Declaración acciones y funciones // Se leen todos los datos hasta encontrar el centinela void LeerDatos(tDatos datos); // Lee un sólo dato y devuelve falso si es el centinela void LeerUnDato(tHabitante &habit); // Se muestran las opciones del menú void MuestraMenu(); // Escribe los datos correspondientes void EscribirUnDato(tHabitante habit); // Consulta los datos con un determinado nombre (num=0), // primer apellido (num=1) o segundo apellido (num=2) dado void ConsultaPorNomAp1Ap2(const tDatos &datos, const int &num); // Consulta los datos con una edad comprendida en un intervalo dado void ConsultaPorEdad(const tDatos &datos); // Programa principal int main() { // Declaracion de variables tDatos datos; bool continuar = true; int opcion; cout << "Entre los datos de los clientes, " << endl; cout << "<Nombre> <PrimerApellido> <SegundoApellido> <Edad>, " << endl; cout << "y finalice con X X X -1:" << endl; LeerDatos(datos); while (continuar) { MuestraMenu(); cin >> opcion; switch (opcion) { case 0: ConsultaPorNomAp1Ap2(datos, 0); break; case 1: ConsultaPorNomAp1Ap2(datos, 1); break; case 2: ConsultaPorNomAp1Ap2(datos, 2); break; case 3: ConsultaPorEdad(datos); break; case 4: cout << "Fin." << endl; continuar = false; break; default: cout << "No has entrado ninguna opcion valida."; cout << endl << "Fin." << endl; continuar = false; break; } } return 0; } // Definición de acciones y funciones // No leemos más datos cuando llegamos al centinela void LeerDatos(tDatos datos) { int i = 0; LeerUnDato(datos[i]); // Obsérvese que para comprobar si estamos ante el centinela es // suficiente comparar el campo de la edad de datos[i] con -1 while ( datos[i].edad != -1 ) { i = i + 1; LeerUnDato(datos[i]); } } void LeerUnDato(tHabitante &habit) { // {PRE: Las palabras tienes un máximo de N caracteres} cin >> habit.nombre; cin >> habit.apellido1; cin >> habit.apellido2; cin >> habit.edad; } void MuestraMenu() { cout << "0.- Consulta por nombre" << endl; cout << "1.- Consulta por primer apellido" << endl; cout << "2.- Consulta por segundo apellido" << endl; cout << "3.- Consulta por intervalo de edad" << endl; cout << "4.- Salir" << endl; }; void EscribirUnDato(tHabitante habit) { cout << '\t' << habit.nombre << ' '; cout << habit.apellido1 << ' '; cout << habit.apellido2 << ' '; cout << habit.edad << endl; } void ConsultaPorNomAp1Ap2(const tDatos &datos, const int &num) { int i = 0; tNombre aux; cout << "Nombre para consultar: " << endl; cin >> aux; // Para determinar si estamos ante el centinela, // es suficiente comprobar si la edad es -1 cout << "Consulta:" << endl; while ( datos[i].edad != -1 ) { switch (num) { case 0: if ( strcmp( datos[i].nombre, aux ) == 0 ) EscribirUnDato( datos[i] ); break; case 1: if ( strcmp( datos[i].apellido1, aux ) == 0 ) EscribirUnDato( datos[i] ); break; case 2: if ( strcmp( datos[i].apellido2, aux ) == 0 ) EscribirUnDato( datos[i] ); break; default: cout << "Mala opcion para el nombre, el primer"; cout << "apellido o el segundo apellido" << endl; break; } i++; } cout << endl; } void ConsultaPorEdad(const tDatos &datos) { int i = 0; int min, max; cout << "Intervalo de edad (dos enteros, el menor y el mayor): "; cin >> min >> max; // Para encontrar el centinela sólo // es suficient comprobar que la edad es -1 cout << "Consulta:" << endl; while ( datos[i].edad != -1 ) { if ( ( datos[i].edad >= min ) && ( datos[i].edad <= max ) ) EscribirUnDato( datos[i] ); i++; } }