Problemas solucionados. ¿Cómo? ¿Qué es lo que modifiqué? Pues bien: lo creé desde 0 otra vez. Solución perfecta en muchas ocasiones, pero eso si, no lo intenten con códigos pequeños, pues va deteriorando poco a poco nuestra capacidad de resolver problemas...
El código reescrito desde 0:
El código reescrito desde 0:
Código (c) [Seleccionar]
#include <stdio.h>
#define INTERROGACION 168
#define EXCLAMACION 173
#define eTILDE 130
#define aTILDE 160
#define iTILDE 161
#define oTILDE 162
#define uTILDE 163
#define eNNE 164
#define LIMPIARBUFFER fflush(stdin)
// si usas linux reemplazar fflush(stdin) por while(getchar() != '\n')
int main() {
struct fCliente {
int cuenta;
char nombre[20], apellidos[40];
float dinero;
} cliente, clienteVacio = {0, "Sin nombre", "Sin apellidos", 0.0};
int opcion, opcion2, cuenta, numero_cuentas, numero_cuentas_no_vacias, i = 0;
float temporal;
char respuesta;
FILE *fichero = fopen("basededatos.dat", "r+");
if(!fichero) {
fichero = fopen("basededatos.dat", "w+");
for(i = 0; i < 500; i++) fwrite(&clienteVacio, sizeof(struct fCliente), 1, fichero);
}
do {
numero_cuentas = 0; numero_cuentas_no_vacias = 0; respuesta = 's';
rewind(fichero);
do {
if(fread(&cliente,sizeof(struct fCliente), 1, fichero))
numero_cuentas++;
if (cliente.cuenta > 0) numero_cuentas_no_vacias++;
} while(!feof(fichero));
rewind(fichero);
//printf("%i y %i\n", numero_cuentas, numero_cuentas_no_vacias); <-- solo para comprobar funcionamiento
printf("%cQu%c desea hacer?\n1. Mostrar lista con todos los clientes\n2. Crear una nueva cuenta\n", INTERROGACION, eTILDE);
printf("3. Editar una cuenta existente\n4. Borrar una cuenta\n5. Salir del programa\nOpci%cn: ", oTILDE);
LIMPIARBUFFER;scanf("%i", &opcion);
switch(opcion) {
case 1:
putchar('\n');
if (numero_cuentas_no_vacias == 0)
printf("Error: el archivo esta vac%co.\n", iTILDE);
else {
printf("%-9s%-19s%-39s%s\n", "Cuenta", "Nombre", "Apellidos", "Dinero");
do {
fread(&cliente, sizeof(struct fCliente), 1, fichero);
if (cliente.cuenta)
printf("%-9i%-19s%-39s%.2f\n", cliente.cuenta, cliente.nombre, cliente.apellidos, cliente.dinero);
} while (--numero_cuentas > 0);
printf("Hay un total de %i cuenta(s).\n", numero_cuentas_no_vacias);
}
putchar('\n');
break;
case 2:
printf("Introduzca el n%cmero de la cuenta en la que se almacenar%c al cliente: ", uTILDE, aTILDE);
do {
LIMPIARBUFFER;scanf("%i", &cuenta);
if(!cuenta)
printf("El n%cmero de cuenta 0 no se puede utilizar. Ingrese otro n%cmero: ", uTILDE, uTILDE);
} while (cuenta == 0);
if (cuenta > numero_cuentas) {
fseek(fichero, sizeof(struct fCliente) * numero_cuentas, SEEK_SET);
while(++numero_cuentas < cuenta)
fwrite(&clienteVacio, sizeof(struct fCliente), 1, fichero);
} else {
fseek(fichero, sizeof(struct fCliente) * (cuenta - 1), SEEK_SET);
fread(&cliente, sizeof(struct fCliente), 1, fichero);
if (cliente.cuenta > 0) {
printf("%cAtenci%cn! La cuenta ya contiene un cliente. %cDesea continuar? (s/n) ", EXCLAMACION, oTILDE, INTERROGACION);
LIMPIARBUFFER;scanf(" %c", &respuesta);
}
}
if (respuesta == 's') {
cliente.cuenta = cuenta;
printf("Introduzca el nombre del cliente: ");
LIMPIARBUFFER;scanf("%[^\n]", cliente.nombre);
printf("Introduzca los apellidos del cliente: ");
LIMPIARBUFFER;scanf("%[^\n]", cliente.apellidos);
printf("Introduzca la cantidad de dinero del cliente: ");
LIMPIARBUFFER;scanf("%f", &cliente.dinero);
}
fseek(fichero, sizeof(struct fCliente) * (cuenta - 1), SEEK_SET);
fwrite(&cliente, sizeof(struct fCliente), 1, fichero);
putchar('\n');
break;
case 3:
if (numero_cuentas_no_vacias == 0)
printf("\nError: el archivo est%c vac%co.\n", aTILDE, iTILDE);
else {
printf("\nIntroduzca la cuenta que desea modificar: ");
LIMPIARBUFFER;scanf("%i", &cuenta);
if(!fseek(fichero, sizeof(struct fCliente) * (cuenta - 1), SEEK_SET)) {
fread(&cliente, sizeof(struct fCliente), 1, fichero);
if (cliente.cuenta == 0)
printf("Error: la cuenta est%c vac%ca o no existe.\n", aTILDE, iTILDE);
else {
printf("\n%cQu%c desea modificar?\n1. Nombre del cliente\n2. Apellidos del cliente\n3. Dinero del cliente\n4. A%cadir/quitar dinero\n5. Cancelar operaci%cn\nOpci%cn: ",
INTERROGACION, eTILDE, eNNE, oTILDE, oTILDE);
LIMPIARBUFFER;scanf("%i", &opcion2);
fseek(fichero, sizeof(struct fCliente) * (cuenta - 1), SEEK_SET);
switch(opcion2) {
case 1:
printf("Introduzca el nuevo nombre del cliente: ");
LIMPIARBUFFER;scanf("%[^\n]", cliente.nombre);
fwrite(&cliente, sizeof(struct fCliente), 1, fichero);
break;
case 2:
printf("Introduzca los nuevos apellidos del cliente: ");
LIMPIARBUFFER;scanf("%[^\n]", cliente.apellidos);
fwrite(&cliente, sizeof(struct fCliente), 1, fichero);
break;
case 3:
printf("Introduzca la nueva cantidad de dinero del cliente: ");
LIMPIARBUFFER;scanf("%f", &cliente.dinero);
fwrite(&cliente, sizeof(struct fCliente), 1, fichero);
break;
case 4:
printf("Introduzca la cantidad de dinero que desea a%cadir/quitar (+/-): ", eNNE);
LIMPIARBUFFER;scanf("%f", &temporal);
cliente.dinero += temporal;
fwrite(&cliente, sizeof(struct fCliente), 1, fichero);
break;
case 5:break;
default:printf("Error: opci%cn incorrecta.\n", oTILDE);
}
}
}
}
putchar('\n');
break;
case 4:
if (numero_cuentas_no_vacias > 0) {
printf("Introduzca la cuenta que desea borrar: ");
LIMPIARBUFFER;scanf("%i", &cuenta);
if (!fseek(fichero, sizeof(struct fCliente) * (cuenta - 1), SEEK_SET)) {
fwrite(&clienteVacio, sizeof(struct fCliente), 1, fichero);
printf("Cuenta eliminada satisfactoriamente.\n");
} else
printf("Error: la cuenta seleccionada no existe.\n");
} else
printf("Error: el archivo est%c vac%co.\n", aTILDE, iTILDE);
putchar('\n');
break;
case 5:break;
default:printf("Error: opcion incorrecta.\n\n");
}
} while (opcion != 5);
fclose(fichero);
return 0;
}