Ejercicio:
Programar una agenda con alumnos en la que se guardarán los siguientes datos: nombre, apellido y edad.
El programa debe:
- Preguntar de cuantos alumnos va a ser la agenda y según la respuesta se deberá reservar ese espacio de manera dinámica.
- Leer los datos de los alumnos.
- Mostrar en pantalla todos los datos de los alumnos.
/****** Inicio programa ******/
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *nombre;
char *apellido;
int edad;
}struct_alum;
int reservaMemoria (struct_alum **alu,int num);
void leerAlumno(char **alu);
void listarDatos(struct_alum *alu,int num);
main()
{
int num,i;
char str[10];
struct_alum *alu;
printf("Cuantos alumnos van a entrar en tu agenda?: ");
gets(str);
sscanf(str,"%d",&num);
reservaMemoria(&alu,num);
printf("\nLectura de datos de los alumnos\n");
printf("-------------------------------\n\n");
for (i=0;i<num;i++)
{
printf("\n");
printf("Datos del alumno %d: \n",i+1);
printf("Nombre: ");
leerAlumno(&alu[i].nombre);
printf("Apellido: ");
leerAlumno(&alu[i].apellido);
printf("Edad: ");
gets(str);
sscanf(str,"%d",&alu[i].edad);
}
listarDatos(alu,num);
getchar();
}
int reservaMemoria (struct_alum **alu,int num)
{
*alu=(struct_alum *)malloc(sizeof(struct_alum)*num);
if (*alu==NULL)
printf("Error reservando memoria\n");
else
printf("Reserva de memoria realizada\n");
}
void leerAlumno(char **alu)
{
char str[30];
gets(str);
*alu=(char *)malloc(strlen(str)+1);
strcpy(*alu,str);
}
void listarDatos(struct_alum *alu,int num)
{
int i;
printf("\nListado de datos de los alumnos\n");
printf("-------------------------------\n\n");
for (i=0;i<num;i++)
{
printf("\n");
printf("Datos del alumno %d: \n",i+1);
printf("Nombre: %s\n",alu[i].nombre);
printf("Apellido: %s\n",alu[i].apellido);
printf("Edad: %d\n\n",alu[i].edad);
}
}
/****** Fin programa******/
Utilizar gets() es peligroso: http://totaki.com/poesiabinaria/2010/04/por-que-no-debemos-utilizar-gets/
ResponderEliminarDe todas formas estás limitando la entrada de datos a 30 caracteres, aunque por el uso de gets() depende de dónde le de el punto al SO de reservarte la memoria que puedas meter más de 30 caracteres o haya una violación de segmento.
Gracias por tu aportación Gaspar.
ResponderEliminarLa función gets() no sólo es peligrosa por la violación de segmento que comenta Gaspar, es peligrosa sencillamente porque si se controla el error de desbordamiento de buffer se puede inyectar un shellcode y ganar control de ejecución sobre tu programa. La violación de segmento es lo mejor que puede pasar, al menos el sistema operativo detiene tu programa porque detecta que se está comportando como no debería.
ResponderEliminarOtra función peligrosa que usas es strcpy(). No controla el número de caracteres que copia, lo que puede (y suele) suponer un fallo de seguridad, por lo mismo que antes. Usa strncpy() / memcpy().
Lo mismo se aplica para strcmp() - strncmp().
C es un lenguaje peligroso si no conoce bien, conviene documentarse antes sobre las funciones que JAMÁS deberían usarse. El 70% de los fallos de seguridad se deben a errores de esta índole.
Gracias de nuevo por vuestras aportaciones.
ResponderEliminarEnriquecen, y mucho, los artículos publicados.
Saludos.