| utiles.h |
#include<stdio.h>
#ifndef __UTILES__
#define __UTILES__
char * sgets(void);
void spause(void);
int confirmar(char * indicacion);
char * pedir(const char * indicacion);
#ifdef __ISDEVC__
#define BORRAR "cls"
int strcasecmp(const char * big, const char * little);
#else
#define BORRAR "clear"
#include<termios.h>
char getch(void);
#endif
#endif
|
| utiles.c |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include "utiles.h"
/*
sgets() has different implementations in Unix and elsewhere,
hence our first step is to determine just what the
underlying OS is
*/
#ifdef __ISDEVC__
/*
This is not Unix, hence no fgetln() and sgets()
is somewhat less safe. We hope the user
will not input more than 1024 characteres at a time.
*/
char * sgets(void)
{
int MAXCHARS = 1024;
char * temp = (char *)malloc(MAXCHARS);
char * resultado;
fgets(temp,MAXCHARS,stdin);
resultado = (char *)malloc(strlen(temp));
strcpy(resultado, temp);
resultado[strlen(resultado)-1] = '\0';
free(temp);
return resultado;
}
/*
strcasecmp() is not defined, hence we
try to produce a reasonable facsimile
*/
int strcasecmp(const char * big, const char * little)
{
int i,n;
char * _big = (char *)malloc(sizeof(char)*(strlen(big)+1));
char * _little = (char *)malloc(sizeof(char)*(strlen(little)+1));
int result;
/*
Store the original values
*/
strcpy(_big, big);
strcpy(_little,little);
/*
Translate into lowercase both _big and _little
*/
n = strlen(_big);
for(i=0;i<n;i++)
_big[i] = tolower(_big[i]);
n = strlen(_little);
for(i=0;i<n;i++)
_little[i] = tolower(_little[i]);
/*
Find out whether little and big are equal
after translating into lowercase
*/
result = strcmp(_big,_little);
/*
No leaks!
*/
free(_big);
free(_little);
/*
And tell what happened
*/
return result;
}
#else
/*
This is Unix, hence fgetln() is available but getch() is not.
We produce a reasonable implementation of sgets() and
of getch()
*/
char * sgets(void)
{
char * puntero_linea;
size_t longitud_linea;
char * resultado;
puntero_linea = fgetln(stdin, &longitud_linea);
resultado = (char *)malloc(longitud_linea+2);
memcpy(resultado,puntero_linea,longitud_linea);
resultado[longitud_linea-1] = '\0';
return resultado;
}
char getch(void) {
struct termios conf_vieja, conf_nueva;
char c;
tcgetattr(0,&conf_vieja);
conf_nueva = conf_vieja;
conf_nueva.c_lflag &= (~ICANON);
conf_nueva.c_cc[VTIME] = 0;
conf_nueva.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&conf_nueva);
c = getchar();
tcsetattr(0,TCSANOW,&conf_vieja);
return c;
}
#endif
/*
Once we have sgets() and getch() at our disposal, we build
further useful functions like pedir (ask) and confirmar
(confirm). All these functions are shared between platforms.
*/
char * pedir(const char * indicacion)
{
char * resultado;
printf("%s ", indicacion);
resultado = sgets();
return resultado;
}
void spause(void)
{
char * temp;
printf("\n\nPulse <INTRO> para continuar\n\n");
temp = sgets();
free(temp);
return;
}
int confirmar(char * indicacion)
{
char * respuesta;
printf("%s (s/n): ", indicacion);
respuesta = sgets();
return toupper(respuesta[0]) == 'S';
}
|
| main.h |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#ifndef __PROGRAMAPRINCIPAL__
#define __PROGRAMAPRINCIPAL__
#include "utiles.h"
#define MAX_REGISTROS 10
struct Registro {
char nombre[20];
int edad;
float talla;
};
typedef struct Global {
struct Registro bdd[MAX_REGISTROS];
} Global;
typedef void (*pfuncion)(Global *);
void dispatcher( char * pm, char * ov[], struct Global * pg, pfuncion pf[]);
void iniciacion(Global * pg, int argc, char * argv[]);
void terminacion(Global * pg);
void ayuda(Global * pg);
void altas(Global * pg);
void bajas(Global * pg);
void modificaciones(Global * pg);
void informes(Global * pg);
void salir(Global * pg);
void mostrar(struct Registro * p);
void rellenar(struct Registro * p);
#endif
|
| main.c |
#include "main.h"
/****************************************************************/
int main(int argc, char * argv[])
{
Global * pg = (Global *)malloc(sizeof(Global));
char menu[] = "A)ltas B)ajas M)odificaciones I)nformes H)Ayuda S)alir";
char * opcionesvalidas[] = {
"A", /* Ojo: el orden de opciones tiene que */
"B", /* ser igual al orden de funciones */
"M",
"I",
"H",
"S"
};
pfuncion pfun[] = {
&altas, /* Ojo: el orden de funciones tiene que ser */
&bajas, /* igual al orden de opciones */
&modificaciones,
&informes,
&ayuda,
&salir,
NULL /* Marcador de fin de lista al estilo de las cadenas */
};
/*
Las opciones válidas pueden ser tanto caracteres individuales
como palabras completas.
*/
iniciacion(pg, argc, argv);
dispatcher( menu,
opcionesvalidas,
pg,
pfun);
terminacion(pg);
puts("\n\nThat's all folks!\n");
return 0;
}
/****************************************************************/
void mostrar(struct Registro * p)
{
printf("%20s %4d %6.2f\n",
p->nombre,
p->edad,
p->talla);
}
void rellenar(struct Registro * p)
{
char * n;
do
{
printf("\nEscriba el nombre: ");
n = sgets();
strcpy(p->nombre, n);
free(n); /* No hay fuga de memoria */
} while (0 == strlen(p->nombre));
do
{
printf("\nEscriba la edad: ");
n = sgets();
p->edad = strtol(n, NULL, 10);
free(n);
} while (p->edad <1 || p->edad >100);
do
{
printf("\nEscriba la talla (cm): ");
n = sgets();
p->talla = strtof(n, NULL);
free(n);
} while (p->talla <=100.0 || p->talla >=230);
}
void iniciacion(Global * pg, int argc, char * argv[])
{
int i;
for(i=0;i<MAX_REGISTROS;i++)
{
strcpy(pg->bdd[i].nombre,"");
pg->bdd[i].edad = 0;
pg->bdd[i].talla = 0.0;
}
}
void altas(Global * pg)
{
int i,n;
n = -1;
printf("\n\nAltas\n\n");
for(i=0;i<MAX_REGISTROS;i++)
if (0 == pg->bdd[i].edad)
{
n = i;
break;
}
if(-1 != n)
rellenar(&(pg->bdd[n]));
else
printf("Base de datos llena!%c\n", 7);
spause();
}
void bajas(Global * pg)
{
int i,n;
char * s;
for(i=0;i<MAX_REGISTROS; i++)
{
if (0 != pg->bdd[i].edad)
{
mostrar(&(pg->bdd[i]));
}
}
printf("\nEscriba el índice del registro que desea eliminar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s);
pg->bdd[n].edad = 0;
spause();
}
void modificaciones(Global * pg)
{
int i,n;
char * s;
for(i=0;i<MAX_REGISTROS; i++)
if (0 != pg->bdd[i].edad)
mostrar(&(pg->bdd[i]));
printf("\nModificaciones\n\nEscriba el índice del registro que desea modificar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s); /* no hay fuga */
rellenar(&(pg->bdd[n]));
spause();
}
void informes(Global * pg)
{
int i,n;
char * s;
printf("\nInformes\n\nEscriba la edad que desea buscar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s); /* No hay fuga */
printf("\nLista de registros hallados\n\n");
for(i=0;i<MAX_REGISTROS; i++)
{
if (n == pg->bdd[i].edad)
{
mostrar(&(pg->bdd[i]));
}
}
printf("\n\nFin de la lista de registros hallados\n\n");
spause();
}
void ayuda(Global * pg)
{
printf("\n\nAyuda\n\n");
spause();
}
void terminacion(Global * pg)
{
int i;
puts("\nEl contenido de la base de datos es:\n\n");
for(i=0;i<MAX_REGISTROS;i++)
mostrar(&(pg->bdd[i]));
printf("\n\nFin del listado\n\n");
}
/****************************************************************/
void dispatcher( char * pm, char * ov[], Global * pg, pfuncion pf[])
{
char * temp = NULL; /* Para leer la instrucción */
int instruccion; /* dada por el usuario */
int num_opciones = 0;
int i;
/* Recuento de opciones */
while(pf[num_opciones] != NULL) num_opciones++;
/* Bucle principal de ejecución */
do
{
printf("%s ", pm);
temp = sgets();
instruccion = -1;
for(i=0;i<num_opciones;i++)
if(0==strcasecmp(ov[i],temp))
{
instruccion = i;
break;
}
system(BORRAR);
if (-1 != instruccion)
pf[instruccion](pg);
else
printf("%c", 7);
free(temp); /* Se libera la memoria reservada por sgets() */
} while (&salir != pf[instruccion]);
} /* Fin de dispatcher() */
/****************************************************************/
void salir(struct Global * pg)
{
return;
}
|
| makefile |
OBJECTS = main.o utiles.o CC = gcc #FLAGS = -D__ISWINDOWS__ FLAGS = -D__ISUNIX__ program: $(OBJECTS) $(CC) $(FLAGS) $(OBJECTS) -o program utiles.o: utiles.c utiles.h $(CC) $(FLAGS) -c utiles.c -o utiles.o main.o: main.c utiles.h main.h $(CC) $(FLAGS) -c main.c clean: rm *.o rm program windows_clean: del *.o del program.exe |
| utiles.h |
#include<stdio.h>
#ifndef __UTILES__
#define __UTILES__
char * sgets(void);
void spause(void);
int confirmar(char * indicacion);
char * pedir(const char * indicacion);
#ifdef __ISDEVC__
#define BORRAR "cls"
int strcasecmp(const char * big, const char * little);
#else
#define BORRAR "clear"
#include<termios.h>
char getch(void);
#endif
#endif
|
| utiles.c |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include "utiles.h"
/*
sgets() has different implementations in Unix and elsewhere,
hence our first step is to determine just what the
underlying OS is
*/
#ifdef __ISDEVC__
/*
This is not Unix, hence no fgetln() and sgets()
is somewhat less safe. We hope the user
will not input more than 1024 characteres at a time.
*/
char * sgets(void)
{
int MAXCHARS = 1024;
char * temp = (char *)malloc(MAXCHARS);
char * resultado;
fgets(temp,MAXCHARS,stdin);
resultado = (char *)malloc(strlen(temp));
strcpy(resultado, temp);
resultado[strlen(resultado)-1] = '\0';
free(temp);
return resultado;
}
/*
strcasecmp() is not defined, hence we
try to produce a reasonable facsimile
*/
int strcasecmp(const char * big, const char * little)
{
int i,n;
char * _big = (char *)malloc(sizeof(char)*(strlen(big)+1));
char * _little = (char *)malloc(sizeof(char)*(strlen(little)+1));
int result;
/*
Store the original values
*/
strcpy(_big, big);
strcpy(_little,little);
/*
Translate into lowercase both _big and _little
*/
n = strlen(_big);
for(i=0;i<n;i++)
_big[i] = tolower(_big[i]);
n = strlen(_little);
for(i=0;i<n;i++)
_little[i] = tolower(_little[i]);
/*
Find out whether little and big are equal
after translating into lowercase
*/
result = strcmp(_big,_little);
/*
No leaks!
*/
free(_big);
free(_little);
/*
And tell what happened
*/
return result;
}
#else
/*
This is Unix, hence fgetln() is available but getch() is not.
We produce a reasonable implementation of sgets() and
of getch()
*/
char * sgets(void)
{
char * puntero_linea;
size_t longitud_linea;
char * resultado;
puntero_linea = fgetln(stdin, &longitud_linea);
resultado = (char *)malloc(longitud_linea+2);
memcpy(resultado,puntero_linea,longitud_linea);
resultado[longitud_linea-1] = '\0';
return resultado;
}
char getch(void) {
struct termios conf_vieja, conf_nueva;
char c;
tcgetattr(0,&conf_vieja);
conf_nueva = conf_vieja;
conf_nueva.c_lflag &= (~ICANON);
conf_nueva.c_cc[VTIME] = 0;
conf_nueva.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&conf_nueva);
c = getchar();
tcsetattr(0,TCSANOW,&conf_vieja);
return c;
}
#endif
/*
Once we have sgets() and getch() at our disposal, we build
further useful functions like pedir (ask) and confirmar
(confirm). All these functions are shared between platforms.
*/
char * pedir(const char * indicacion)
{
char * resultado;
printf("%s ", indicacion);
resultado = sgets();
return resultado;
}
void spause(void)
{
char * temp;
printf("\n\nPulse <INTRO> para continuar\n\n");
temp = sgets();
free(temp);
return;
}
int confirmar(char * indicacion)
{
char * respuesta;
printf("%s (s/n): ", indicacion);
respuesta = sgets();
return toupper(respuesta[0]) == 'S';
}
|
| main.h |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#ifndef __PROGRAMAPRINCIPAL__
#define __PROGRAMAPRINCIPAL__
#include "utiles.h"
#define MAX_REGISTROS 10000
struct Registro {
char nombre[20];
int edad;
float talla;
};
typedef struct Global {
struct Registro bdd[MAX_REGISTROS];
} Global;
typedef void (*pfuncion)(Global *);
void dispatcher( char * pm, char * ov[], struct Global * pg, pfuncion pf[]);
void iniciacion(Global * pg, int argc, char * argv[]);
void terminacion(Global * pg);
void ayuda(Global * pg);
void altas(Global * pg);
void bajas(Global * pg);
void modificaciones(Global * pg);
void informes(Global * pg);
void salir(Global * pg);
void mostrar(struct Registro * p);
void rellenar(struct Registro * p);
void abrir(Global * p);
void guardar(Global * p);
#endif
|
| main.c |
#include "main.h"
/****************************************************************/
int main(int argc, char * argv[])
{
Global * pg = (Global *)malloc(sizeof(Global));
char menu[] = "O)Abrir G)uardar A)ltas B)ajas M)odificaciones I)nformes H)Ayuda S)alir";
char * opcionesvalidas[] = {
"O",
"G",
"A", /* Ojo: el orden de opciones tiene que */
"B", /* ser igual al orden de funciones */
"M",
"I",
"H",
"S"
};
pfuncion pfun[] = {
&abrir,
&guardar,
&altas, /* Ojo: el orden de funciones tiene que ser */
&bajas, /* igual al orden de opciones */
&modificaciones,
&informes,
&ayuda,
&salir,
NULL /* Marcador de fin de lista al estilo de las cadenas */
};
/*
Las opciones válidas pueden ser tanto caracteres individuales
como palabras completas.
*/
iniciacion(pg, argc, argv);
dispatcher( menu,
opcionesvalidas,
pg,
pfun);
terminacion(pg);
puts("\n\nThat's all folks!\n");
return 0;
}
/****************************************************************/
void mostrar(struct Registro * p)
{
printf("%20s %4d %6.2f\n",
p->nombre,
p->edad,
p->talla);
}
void rellenar(struct Registro * p)
{
char * n;
do
{
printf("\nEscriba el nombre: ");
n = sgets();
strcpy(p->nombre, n);
free(n); /* No hay fuga de memoria */
} while (0 == strlen(p->nombre));
do
{
printf("\nEscriba la edad: ");
n = sgets();
p->edad = strtol(n, NULL, 10);
free(n);
} while (p->edad <=0 || p->edad >100);
do
{
printf("\nEscriba la talla (cm): ");
n = sgets();
p->talla = strtof(n, NULL);
free(n);
} while (p->talla <=1.0 || p->talla >=230);
}
void iniciacion(Global * pg, int argc, char * argv[])
{
int i;
for(i=0;i<MAX_REGISTROS;i++)
{
strcpy(pg->bdd[i].nombre,"");
pg->bdd[i].edad = 0;
pg->bdd[i].talla = 0.0;
}
}
void altas(Global * pg)
{
int i,n;
n = -1;
printf("\n\nAltas\n\n");
for(i=0;i<MAX_REGISTROS;i++)
if (0 == pg->bdd[i].edad)
{
n = i;
break;
}
if(-1 != n)
rellenar(&(pg->bdd[n]));
else
printf("Base de datos llena!%c\n", 7);
spause();
}
void bajas(Global * pg)
{
int i,n;
char * s;
for(i=0;i<MAX_REGISTROS; i++)
if (0 == pg->bdd[i].edad)
mostrar(&(pg->bdd[i]));
printf("\nEscriba el índice del registro que desea eliminar: ");
s = sgets();
n = strtol(s, NULL, 10);
pg->bdd[n].edad = 0;
spause();
}
void modificaciones(Global * pg)
{
int i,n;
char * s;
for(i=0;i<MAX_REGISTROS; i++)
if (0 != pg->bdd[i].edad)
mostrar(&(pg->bdd[i]));
printf("\nModificaciones\n\nEscriba el índice del registro que desea modificar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s); /* no hay fuga */
rellenar(&(pg->bdd[n]));
spause();
}
void informes(Global * pg)
{
int i,n;
char * s;
printf("\nInformes\n\nEscriba la edad que desea buscar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s); /* No hay fuga */
printf("\nLista de registros hallados\n\n");
for(i=0;i<MAX_REGISTROS; i++)
if (n == pg->bdd[i].edad)
mostrar(&(pg->bdd[i]));
printf("\n\nFin de la lista de registros hallados\n\n");
spause();
}
void ayuda(Global * pg)
{
printf("\n\nAyuda\n\n");
spause();
}
void terminacion(Global * pg)
{
int i;
puts("\nEl contenido de la base de datos es:\n\n");
for(i=0;i<MAX_REGISTROS;i++)
mostrar(&(pg->bdd[i]));
printf("\n\nFin del listado\n\n");
}
/****************************************************************/
void dispatcher( char * pm, char * ov[], Global * pg, pfuncion pf[])
{
char * temp = NULL; /* Para leer la instrucción */
int instruccion; /* dada por el usuario */
int num_opciones = 0;
int i;
/* Recuento de opciones */
while(pf[num_opciones] != NULL) num_opciones++;
/* Bucle principal de ejecución */
do
{
printf("%s ", pm);
temp = sgets();
instruccion = -1;
for(i=0;i<num_opciones;i++)
if(0==strcasecmp(ov[i],temp))
{
instruccion = i;
break;
}
system(BORRAR);
if (-1 != instruccion)
pf[instruccion](pg);
else
printf("%c", 7);
free(temp); /* Se libera la memoria reservada por sgets() */
} while (&salir != pf[instruccion]);
} /* Fin de dispatcher() */
/****************************************************************/
void salir(struct Global * pg)
{
return;
}
void abrir(Global * pg)
{
FILE * fp;
fp = fopen("datos.bin", "rb");
fread(pg->bdd, sizeof(pg->bdd), 1, fp);
fclose(fp);
}
void guardar(Global * pg)
{
FILE * fp;
fp = fopen("datos.bin", "wb");
fwrite(pg->bdd, sizeof(pg->bdd), 1, fp);
/* fwrite(pg->bdd, sizeof(struct Registro), MAX_REGISTROS, fp); */
fclose(fp);
}
|
| makefile |
OBJECTS = main.o utiles.o program: $(OBJECTS) cc $(OBJECTS) -o program utiles.o: utiles.c utiles.h cc -c utiles.c -o utiles.o main.o: main.c utiles.h main.h cc -c main.c clean: rm utiles.o rm *.o rm program |
| utiles.h |
#include<stdio.h>
#ifndef __UTILES__
#define __UTILES__
char * sgets(void);
void spause(void);
int confirmar(char * indicacion);
char * pedir(const char * indicacion);
#ifdef __ISDEVC__
#define BORRAR "cls"
int strcasecmp(const char * big, const char * little);
#else
#define BORRAR "clear"
#include<termios.h>
char getch(void);
#endif
#endif
|
| utiles.c |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include "utiles.h"
/*
sgets() has different implementations in Unix and elsewhere,
hence our first step is to determine just what the
underlying OS is
*/
#ifdef __ISDEVC__
/*
This is not Unix, hence no fgetln() and sgets()
is somewhat less safe. We hope the user
will not input more than 1024 characteres at a time.
*/
char * sgets(void)
{
int MAXCHARS = 1024;
char * temp = (char *)malloc(MAXCHARS);
char * resultado;
fgets(temp,MAXCHARS,stdin);
resultado = (char *)malloc(strlen(temp));
strcpy(resultado, temp);
resultado[strlen(resultado)-1] = '\0';
free(temp);
return resultado;
}
/*
strcasecmp() is not defined, hence we
try to produce a reasonable facsimile
*/
int strcasecmp(const char * big, const char * little)
{
int i,n;
char * _big = (char *)malloc(sizeof(char)*(strlen(big)+1));
char * _little = (char *)malloc(sizeof(char)*(strlen(little)+1));
int result;
/*
Store the original values
*/
strcpy(_big, big);
strcpy(_little,little);
/*
Translate into lowercase both _big and _little
*/
n = strlen(_big);
for(i=0;i<n;i++)
_big[i] = tolower(_big[i]);
n = strlen(_little);
for(i=0;i<n;i++)
_little[i] = tolower(_little[i]);
/*
Find out whether little and big are equal
after translating into lowercase
*/
result = strcmp(_big,_little);
/*
No leaks!
*/
free(_big);
free(_little);
/*
And tell what happened
*/
return result;
}
#else
/*
This is Unix, hence fgetln() is available but getch() is not.
We produce a reasonable implementation of sgets() and
of getch()
*/
char * sgets(void)
{
char * puntero_linea;
size_t longitud_linea;
char * resultado;
puntero_linea = fgetln(stdin, &longitud_linea);
resultado = (char *)malloc(longitud_linea+2);
memcpy(resultado,puntero_linea,longitud_linea);
resultado[longitud_linea-1] = '\0';
return resultado;
}
char getch(void) {
struct termios conf_vieja, conf_nueva;
char c;
tcgetattr(0,&conf_vieja);
conf_nueva = conf_vieja;
conf_nueva.c_lflag &= (~ICANON);
conf_nueva.c_cc[VTIME] = 0;
conf_nueva.c_cc[VMIN] = 1;
tcsetattr(0,TCSANOW,&conf_nueva);
c = getchar();
tcsetattr(0,TCSANOW,&conf_vieja);
return c;
}
#endif
/*
Once we have sgets() and getch() at our disposal, we build
further useful functions like pedir (ask) and confirmar
(confirm). All these functions are shared between platforms.
*/
char * pedir(const char * indicacion)
{
char * resultado;
printf("%s ", indicacion);
resultado = sgets();
return resultado;
}
void spause(void)
{
char * temp;
printf("\n\nPulse <INTRO> para continuar\n\n");
temp = sgets();
free(temp);
return;
}
int confirmar(char * indicacion)
{
char * respuesta;
printf("%s (s/n): ", indicacion);
respuesta = sgets();
return toupper(respuesta[0]) == 'S';
}
|
| main.h |
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#ifndef __PROGRAMAPRINCIPAL__
#define __PROGRAMAPRINCIPAL__
#include "utiles.h"
#define MAX_REGISTROS 10000
struct Registro {
char nombre[20];
int edad;
float talla;
};
typedef struct Global {
struct Registro *bdd;
int num_registros;
} Global;
typedef void (*pfuncion)(Global *);
void dispatcher( char * pm, char * ov[], struct Global * pg, pfuncion pf[]);
void iniciacion(Global * pg, int argc, char * argv[]);
void terminacion(Global * pg);
void ayuda(Global * pg);
void altas(Global * pg);
void bajas(Global * pg);
void modificaciones(Global * pg);
void informes(Global * pg);
void salir(Global * pg);
void mostrar(struct Registro * p);
void rellenar(struct Registro * p);
void abrir(Global * p);
void guardar(Global * p);
#endif
|
| main.c |
#include "main.h"
/****************************************************************/
int main(int argc, char * argv[])
{
Global * pg = (Global *)malloc(sizeof(Global));
char menu[] = "O)Abrir G)uardar A)ltas B)ajas M)odificaciones I)nformes H)Ayuda S)alir";
char * opcionesvalidas[] = {
"O",
"G",
"A", /* Ojo: el orden de opciones tiene que */
"B", /* ser igual al orden de funciones */
"M",
"I",
"H",
"S"
};
pfuncion pfun[] = {
&abrir,
&guardar,
&altas, /* Ojo: el orden de funciones tiene que ser */
&bajas, /* igual al orden de opciones */
&modificaciones,
&informes,
&ayuda,
&salir,
NULL /* Marcador de fin de lista al estilo de las cadenas */
};
/*
Las opciones válidas pueden ser tanto caracteres individuales
como palabras completas.
*/
iniciacion(pg, argc, argv);
dispatcher( menu,
opcionesvalidas,
pg,
pfun);
terminacion(pg);
puts("\n\nThat's all folks!\n");
return 0;
}
/****************************************************************/
void mostrar(struct Registro * p)
{
printf("%20s %4d %6.2f\n",
p->nombre,
p->edad,
p->talla);
}
void rellenar(struct Registro * p)
{
char * n;
do
{
printf("\nEscriba el nombre: ");
n = sgets();
strcpy(p->nombre, n);
free(n); /* No hay fuga de memoria */
} while (0 == strlen(p->nombre));
do
{
printf("\nEscriba la edad: ");
n = sgets();
p->edad = strtol(n, NULL, 10);
free(n);
} while (p->edad <=0 || p->edad >100);
do
{
printf("\nEscriba la talla (cm): ");
n = sgets();
p->talla = strtof(n, NULL);
free(n);
} while (p->talla <=1.0 || p->talla >=230);
}
void iniciacion(Global * pg, int argc, char * argv[])
{
int i;
pg->bdd = NULL;
}
void altas(Global * pg)
{
int i,n;
n = -1;
printf("\n\nAltas\n\n");
for(i=0;i<pg->num_registros;i++)
if (0 == pg->bdd[i].edad)
{
n = i;
break;
}
if(-1 != n)
rellenar(&(pg->bdd[n]));
else
printf("Base de datos llena o inexistente%c\n", 7);
spause();
}
void bajas(Global * pg)
{
int i,n;
char * s;
int num_posibles_bajas = 0;
for(i=0;i<pg->num_registros; i++)
if (0 != pg->bdd[i].edad)
{
mostrar(&(pg->bdd[i]));
num_posibles_bajas++;
};
if(0 == num_posibles_bajas)
{
printf("\n\nBase de datos vacía\n\n");
}
else
{
printf("\nEscriba el índice del registro que desea eliminar: ");
s = sgets();
n = strtol(s, NULL, 10);
pg->bdd[n].edad = 0;
}
spause();
}
void modificaciones(Global * pg)
{
int i,n;
char * s;
int num_posibles_modificaciones = 0;
for(i=0;i<pg->num_registros; i++)
if (0 != pg->bdd[i].edad)
{
mostrar(&(pg->bdd[i]));
num_posibles_modificaciones++;
}
if (0 == num_posibles_modificaciones)
{
printf("\n\nBase de datos vacía o inexistente\n\n");
}
else
{
printf("\nModificaciones\n\nEscriba el índice del registro que desea modificar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s); /* no hay fuga */
rellenar(&(pg->bdd[n]));
}
spause();
}
void informes(Global * pg)
{
int i,n;
char * s;
if (0 == pg->num_registros)
{
printf("\n\nBase de datos vacía.\n\n");
}
else
{
printf("\nInformes\n\nEscriba la edad que desea buscar: ");
s = sgets();
n = strtol(s, NULL, 10);
free(s); /* No hay fuga */
printf("\nLista de registros hallados\n\n");
for(i=0;i<pg->num_registros; i++)
if (n == pg->bdd[i].edad)
mostrar(&(pg->bdd[i]));
printf("\n\nFin de la lista de registros hallados\n\n");
}
spause();
}
void ayuda(Global * pg)
{
printf("\n\nAyuda\n\n");
spause();
}
void terminacion(Global * pg)
{
int i;
if (0 == pg->num_registros)
{
printf("\n\nBase de datos vacía.\n\n");
}
else
{
puts("\nEl contenido de la base de datos es:\n\n");
for(i=0;i<pg->num_registros;i++)
if (0 != pg->bdd[i].edad)
mostrar(&(pg->bdd[i]));
printf("\n\nFin del listado\n\n");
free(pg->bdd);
}
}
/****************************************************************/
void dispatcher( char * pm, char * ov[], Global * pg, pfuncion pf[])
{
char * temp = NULL; /* Para leer la instrucción */
int instruccion; /* dada por el usuario */
int num_opciones = 0;
int i;
/* Recuento de opciones */
while(pf[num_opciones] != NULL) num_opciones++;
/* Bucle principal de ejecución */
do
{
printf("%s ", pm);
temp = sgets();
instruccion = -1;
for(i=0;i<num_opciones;i++)
if(0==strcasecmp(ov[i],temp))
{
instruccion = i;
break;
}
system(BORRAR);
if (-1 != instruccion)
pf[instruccion](pg);
else
printf("%c", 7);
free(temp); /* Se libera la memoria reservada por sgets() */
} while (&salir != pf[instruccion]);
} /* Fin de dispatcher() */
/****************************************************************/
void salir(struct Global * pg)
{
if (confirmar("Desea guardar los cambios?"))
guardar(pg);
else
printf("\n\nNo se han guardado los cambios.\n\n");
return;
}
void abrir(Global * pg)
{
FILE * fp;
struct Registro registro = {"", 0, 0.0 };
int i;
fp = fopen("datos.bin", "rb");
if (NULL == fp)
{
/* la base de datos no existe, la creamos */
fp = fopen("datos.bin", "wb");
for(i=0;i<MAX_REGISTROS;i++)
fwrite(®istro, sizeof(struct Registro),1,fp);
fclose(fp);
printf("\n\nBase de datos creada... por favor, arranque de nuevo.\n\n");
exit(0);
}
else
{
/* Calculamos el número de registros que hay en el archivo */
fseek(fp,0,SEEK_END);
pg->num_registros = ftell(fp)/sizeof(struct Registro);
printf("\n\nSe han leído %d registros\n", pg->num_registros);
/* Creamos un bloque de tamaño adecuado */
pg->bdd = calloc(pg->num_registros,sizeof(struct Registro));
/* Ponemos el puntero de archivo al principio */
fseek(fp,0,SEEK_SET);
fread(pg->bdd, sizeof(struct Registro), pg->num_registros, fp);
fclose(fp);
}
}
void guardar(Global * pg)
{
FILE * fp;
if (0 != pg->num_registros)
{
fp = fopen("datos.bin", "wb");
fwrite(pg->bdd, sizeof(struct Registro), pg->num_registros, fp);
fclose(fp);
}
else
{
printf("\n\nLa base de datos está vacía y no se ha guardado.\n\n");
}
}
|
| makefile |
OBJECTS = main.o utiles.o program: $(OBJECTS) cc $(OBJECTS) -o program utiles.o: utiles.c utiles.h cc -c utiles.c -o utiles.o main.o: main.c utiles.h main.h cc -c main.c clean: rm utiles.o rm *.o rm program |