#include <stdio.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
char nombre[30];
char direccion[30];
int edad;
}alumno;
enum NumError
{
NUM_OK,
NUM_OUT_OF_RANGE,
NUM_NOT_FOUND
};
enum StrError
{
STR_OK,
STR_NULL,
STR_EMPTY
};
enum StrError get_StringCin(char * tmp , int size);
enum NumError get_NumCin(int * num, int limitL, int limitH);
void flushCin(void);
int main(void)
{
alumno *ptrStructAlumno= NULL; // Puntero a estructura ubicada en el heap
int max = 0; // Mantiene la cantidad de alumnos ingresados
int itmp; // Variable auxiliar
do
{
//system("reset");
/*
* Pedido de memoria del heap
*
*/
alumno *ptrtmp = NULL; // Puntero auxiliar
ptrtmp
= ( alumno
* )realloc( ptrStructAlumno
, (max
+1)*sizeof(alumno
)); if( ptrtmp == NULL )
{
/*
* ERROR, no es posible asignar la memoria, limpiamos y salimos.
*/
printf("\n No se pudo asignar la memoria!"); if(ptrStructAlumno!=NULL)
{
}
}
else
{
/*
* Fue posible asignar la memoria, procedemos a reasignar el puntero
*/
ptrStructAlumno = ptrtmp;
}
/*
* Comenzamos con los pedidos de datos string
*/
printf("\n Ingresa el nombre del alumno [%d]......:", max
+1); while(get_StringCin((ptrStructAlumno+max)->nombre,sizeof (ptrStructAlumno+max)->nombre) != STR_OK)
{
printf("\n Ingresa el nombre del alumno de forma correcta [%d]...:", max
+1); }
printf("\n Ingresa la direccion del alumno [%d]...:", max
+1); while(get_StringCin((ptrStructAlumno+max)->direccion,sizeof (ptrStructAlumno+max)->direccion) != STR_OK)
{
printf("\n Ingresa la direccion del alumno de forma correcta [%d]...:", max
+1); }
/*
* Pedidos de datos numericos
*/
printf("\n Ingresa la edad del alumno [%d]........:", max
+1); while(get_NumCin(&(ptrStructAlumno->edad),1,100) != NUM_OK)
{
// Numero ERRONEO
printf("\n Por favor Ingresa edad del alumno con numeros desde 1-100 [%d]........:", max
+1); }
printf( "\n 1 - Finaliza \n 2 - Agrega alumno\n Ingrese opcion...: " ); while(get_NumCin(&itmp,1,2) != NUM_OK)
{
//Numero ERRONEO
printf( "\n El dato ingresado no es una opcion valida, reingrese su opcion" ); printf( "\n 1 - Finaliza \n 2 - Agrega alumno\n Ingrese opcion...: " ); }
max++;
}while( itmp == 2 );
for ( itmp = 0; itmp < max; itmp++ )
{
printf( "\n%s\t%s\t%d",(ptrStructAlumno
+itmp
)->nombre
, (ptrStructAlumno
+itmp
)->direccion
, (ptrStructAlumno
+itmp
)->edad
); }
// Liberamos memoria
return EXIT_SUCCESS;
}
/*
* Funcion que toma un string desde CIN
* Ademas procede a limpiar CIN
*
*/
enum StrError get_StringCin(char * str, int size)
{
char * tmp;
tmp
= fgets( str
, size
, stdin
);
// Chequeo que no se presiono Ctrl+D (Unix) o Ctrl+Z (Windows)
if(tmp == NULL)
{
return STR_NULL;
}
// Falta chk de linea vacia o con solo espacios en blancos.
// Falta eliminacion de whitespaces al comienzo y/o final de la trama
if(tmp)
{
*tmp='\0';
}
else
{
flushCin();
}
return STR_OK;
}
/*
* Funcion que lee la entrada CIN esperando un numero y luego procede
* a comprobar que se encuentra dentro de los valores limites dados.
*
* Return:
*
* Devuelve los siguientes valores:
*
* NUM_OK : El numero fue encontrado y se encuentra dentro del rango
* NUM_OUT_OF_RANGE : Se encontro un numero pero esta fuera del rango dado
* NUM_NOT_FOUND : Caso en que no se encuentro ningun numero en cin
*
*
* Para eliminar los limites, usar:
*
* Con signo:
* get_NumCin(&numero,INT_MIN,INT_MAX);
* Sin signo:
* get_NumCin(&numero,0,INT_MAX);
*/
enum NumError get_NumCin(int * num, int limitL, int limitH)
{
int j;
flushCin();
if(j == 1)
{
if((*num >= limitL) && (*num<=limitH))
{
return NUM_OK;
}
else
{
return NUM_OUT_OF_RANGE;
}
}
return NUM_NOT_FOUND;
}
/*
* Funcion que permite la limpieza de CIN
*/
void flushCin(void)
{
char ch;
while ((ch
= getchar()) != '\n' && ch
!= EOF
); }