Tabla de fichas Indice del Tema 0204
0201 0202 0203 0204 0205 0206 0207 0208

APLICACIÓN DEL TIPO STRUCT - FICHA DE UN ALUMNO


Nuestro objetIvo es reproducir los apartados o campos que se hallan en la ficha de un alumno. Tomemos nota de los campos más habituales

A su vez, las Direcciones se subdividen en Calle, Número, Piso o planta, Puerta, Localidad, Provincia, Código postal y Estado. Las Calificaciones suelen estar formadas por dos columnas al menos, una para la fecha y otra para la calificación en sí. Por último, el comentario es un bloque de texto sin más estructura. A la vista de esto, cabe pensar en la necesidad de crear una estructura para Direcciones y otra para Calificaciones; la ficha del alumno contendrá posiblemente más de un campo de este tipo. La implementación de estas estructuras de datos puede entonces ser como la que se ve a continuación.
struct Direccion { /* Obsérvese la ausencia de acentos */
	char calle[40];
	char numero[5];
	char piso[5];
	char puerta[4];
	char localidad[40];
	char provincia[15];
	char cod_postal[12];
	char estado[20]; }; /* No definimos variables de este tipo */

struct Calificacion { /* De nuevo sin acentos */
	char fecha[20];
	float nota; };


Empleando una metodología de diseño ascendente, crearemos a continuación una estructura de Ficha, que puede ser la siguiente:

struct Ficha {	/* Basada en Direccion y Calificacion */
	char ape1[20], ape2[20];
	char nombre[20];
	struct Direccion dir_local;
	struct Direccion dir_familiar;
	char nacionalidad[20];
	char num_curso [12]; /* Entre primero y sexto */
	char grupo[2]; /* Una letra o número */
	char curso_academico[10]; /* Por ejemplo, 1998-99 */
	struct Calificacion parcial_1, parcial_2, parcial_3;
	char comentarios[1024]; };

Este es el resultado final: una estructura que engloba todos los datos solicitados. En un ejercicio sencillo como este no se va a imponer ningún criterio de validez de datos; más adelante veremos que es absolutamente crucial impedir dentro de lo posible que el usuario inserte información incorrecta. Anticipándonos al futuro, diremos que el número de líneas de código destinadas a detectar errores en los datos, y a permitir que el usuario corrija esos errores, resulta mucho mayor que el número de líneas dedicado a la lectura de información en sí.

Ejercicio.- Construir un programa que lea de teclado los datos de un alumno y muestre en pantalla su ficha, dándole un aspecto razonable. Se recomienda hacer uso de los indicadores de especificación de formato.
/*
 Ficha de un alumno.
 Ejercicio.- Construir un programa que lea de teclado los datos de un alumno
 y muestre en pantalla su ficha, dándole un aspecto razonable.
 Se recomienda 	hacer uso de los indicadores de especificación de formato.
 Pista: conviene emplear funciones de cadenas,específicamente
 strcat() y strlen().
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

/* Reproducimos las estructuras de datos necesarias */

struct Direccion { /* Obsérvese la ausencia de acentos */
 char calle[40];
 char numero[5];
 char piso[5];
 char puerta[4];
 char localidad[40];
 char provincia[15];
 char cod_postal[12];
 char estado[20]; }; /* No definimos variables de este tipo */

struct Calificacion { /* De nuevo sin acentos */
 char fecha[20];
 float nota; };
 
struct Ficha { /* Basada en Direccion y Calificacion */
 char ape1[20], ape2[20];
 char nombre[20];
 struct Direccion dir_local;
 struct Direccion dir_familiar;
 char nacionalidad[20];
 char num_curso [12]; /* Entre primero y sexto */
 char grupo[2]; /* Una letra o número */
 char curso_academico[10]; /* Por ejemplo, 2004-05 */
 struct Calificacion parcial_1, parcial_2, parcial_3;
 char comentarios[1024]; };

struct Ficha f; /* Declaramos una variable */
int main(void)
{
 /* Fase de lectura de datos */
 printf("Datos académicos\n\n");
 printf("Apellidos y nombre.- Primer apellido        : ");
 gets(f.ape1);
 printf("\nEscriba ahora el segundo apellido, por favor: ");
 gets(f.ape2);
 printf("\nPor último, escriba el nombre               : ");
 gets(f.nombre);
 
 /* Lectura de datos familiares */
 printf("\nDirección familiar.- Por favor, escriba la Calle : ");
 /* Aquí podríamos decir "O pulse INTRO si es la misma que
  la dirección familiar". El programa podría entonces
  copiar la dirección familiar en la local. Lo dejaremos
  como ejercicio para el lector.
 */
 gets(f.dir_familiar.calle);
 printf("\nNúmero                                           : ");
 gets(f.dir_familiar.numero);
 printf("\nPiso                                             : ");
 gets(f.dir_familiar.piso);
 printf("\nY la puerta                                      : ");
 gets(f.dir_familiar.puerta);
 printf("\nPor favor, escriba  el nombre de su localidad    : ");
 gets(f.dir_familiar.localidad);
 printf("\nTambién necesitamos la provincia                 : ");
 gets(f.dir_familiar.provincia);
 printf("\nY el código postal                               : ");
 gets(f.dir_familiar.cod_postal);
 printf("\nPor último, escriba su estado                    : ");
 gets(f.dir_familiar.estado);
 
 /* Lectura de datos locales */
 
 printf("\nDirección local   .- Por favor, escriba la Calle : ");
 gets(f.dir_local.calle);
 printf("\nNúmero                                           : ");
 gets(f.dir_local.numero);
 printf("\nPiso                                             : ");
 gets(f.dir_local.piso);
 printf("\nY la puerta                                      : ");
 gets(f.dir_local.puerta);
 printf("\nPor favor, escriba  el nombre de su localidad    : ");
 gets(f.dir_local.localidad);
 printf("\nTambién necesitamos la provincia                 : ");
 gets(f.dir_local.provincia);
 printf("\nY el código postal                               : ");
 gets(f.dir_local.cod_postal);
 printf("\nPor último, escriba su estado                    : ");
 gets(f.dir_local.estado);
 printf("\nPor favor, escriba su nacionalidad               : ");
 gets(f.nacionalidad);
 printf("\ny el curso en que está matriculado (1..6)        : ");
 gets(f.num_curso);
 printf("\nIndique también el grupo al que pertenece        : ");
 gets(f.grupo);
 printf("\nEscriba el curso académico                       : ");
 gets(f.curso_academico);
 
 /* Lectura de calificaciones */
 
 printf("\n\nCalificaciones");
 printf("\n\nEscriba la fecha del primer parcial                : ");
 gets(f.parcial_1.fecha);
 printf("\ny la calificación obtenida                       : ");
 scanf("%f%*c",&f.parcial_1.nota);
 printf("\n\nEscriba la fecha del segundo parcial                : ");
 gets(f.parcial_2.fecha);
 printf("\ny la calificación obtenida                       : ");
 scanf("%f%*c",&f.parcial_2.nota);
 printf("\n\nEscriba la fecha del tercer parcial                : ");
 gets(f.parcial_3.fecha);
 printf("\ny la calificación obtenida                       : ");
 scanf("%f%*c", &f.parcial_3.nota);
 printf("\n\nPuede escribir comentarios (menos de 1000 caracteres.\n\n:");
 gets(f.comentarios);
 
 /* Fase de impresión de resultados */
 
 printf("Los datos insertados para el alumno son los siguientes:\n\n");
 
 /* Datos personales */
 
 printf("Apellidos y nombre: %s %s, %s\n", f.ape1, f.ape2, f.nombre);
 printf("Nacionalidad: %s  Curso: %s  Grupo: %s  Curso académico %s\n",
    f.nacionalidad, f.num_curso, f.grupo, f.curso_academico);
 printf("\nDirección local: %s, nº %s, piso %s, puerta %s\n", f.dir_local.calle,
    f.dir_local.numero, f.dir_local.piso, f.dir_local.puerta);
 printf("Localidad: %s, Provincia de : %s, Código postal: %s\n",
    f.dir_local.localidad, f.dir_local.provincia, f.dir_local.cod_postal);
 printf("\nDirección familiar: %s, nº %s, piso %s, puerta %s\n", f.dir_familiar.calle,
    f.dir_familiar.numero, f.dir_familiar.piso, f.dir_familiar.puerta);
 printf("Localidad: %s, Provincia de : %s, Código postal: %s\n",
    f.dir_familiar.localidad, f.dir_familiar.provincia, f.dir_familiar.cod_postal);
 
 /* Expediente */
 
 printf("\nCalificaciones\n");
 printf("Fecha: %s --- Nota : %4.2f\n",f.parcial_1.fecha, f.parcial_1.nota);
 printf("Fecha: %s --- Nota : %4.2f\n",f.parcial_2.fecha, f.parcial_2.nota);
 printf("Fecha: %s --- Nota : %4.2f\n",f.parcial_3.fecha, f.parcial_3.nota);
 
 /* Fase de terminación */
 
 puts("\n\nTerminación normal del programa.\n");
 
 return 0;
}

Cuestiones
Realizar un análisis, diseño, implementación y depuración del programa. ¿Cómo sería su documentación?
El paso de depuración muestra que no se han imprimido los comentarios. Corregir el programa.

¿Se puede mejorar la presentación de la salida? Usar especificadores de formato.

Ejercicios propuestos


  1. Ejercicio 0204r01.- Un centro de enseñanza imparte docencia a varios cursos, dentro de cada uno de los cuales existen varios grupos. Construir las estructuras de datos necesarias para: Estas estructuras se utilizarán en distintos subprogramas de un mismo programa, con objeto de manejar la información relativa a un centro educativo. Se prohibe la duplicidad de códigos.

  2. Ejercicio 0204r02.- Escribir un subprograma dotado de las opciones y funciones necesarias (altas, bajas, modificaciones) para manejar la lista de asignaturas del centro (con la capacidad de leer/escribir toda la información en disco).

  3. Ejercicio 0204r03.-Escribir un subprograma programa análogo al anterior, para manejar los datos de los alumnos individuales (con la capacidad de leer/escribir toda la información en disco).

  4. Ejercicio 0204r04.- Escribir un programa análogo al anterior, para manejar los datos de profesores (con la capacidad de leer/escribir toda la información en disco).

  5. Ejercicio 0204r05.- Escribir un subprograma programa análogo al anterior, para manejar los datos de matriculación (con la opción de leer/escribir toda la información en disco).

  6. Ejercicio 0204r06.- Escribir un subprograma que emita listados de alumnos por asignaturas.

  7. Ejercicio 0204r07.- Escribir un subprograma que emita listados de asignaturas por alumnos.

  8. Ejercicio 0204r08.- Escribir un subprograma que emita listados de asignaturas por profesores.