Autor
|
Tema: Problema con archivos de acceso directo (Leído 2,427 veces)
|
TheWarriorVicent
Desconectado
Mensajes: 3
|
He estado intentando crear un programa que simule una base de datos utilizando un archivo de acceso directo. Sin embargo, me han surgido unos cuantos problemas con el código: -No reconoce si el archivo está vacío para comunicárselo al usuario. -Muestra dos veces las cuentas creadas, en lugar de una. -No borra las cuentas (que en realidad lo que se hace, en lugar de borrar texto, sustituir este por un "usuario vacio" que se ignora y no es mostrado). #include <stdio.h> #include <string.h> struct fichaCliente { // tamaño: 68 bits int cuenta; char nombre[15], apellidos[45]; float dinero; } cliente, clienteVacio = {0, "", "", 0.0}; short numero_cuentas = 0; void mostrarClientes(FILE *); void editarCliente(FILE *); void crearCliente(FILE *); void eliminarCliente(FILE *); void comprobarCantidad(FILE *); void asistenteCreacionCliente(int); int main() { int opcion; FILE *basedatos; if (!(basedatos = fopen("base_de_datos.dat", "a+"))) perror("No se ha podido abrir el fichero.\n"); else { do { printf("%s\n%s\n%s\n%s\n%s\n%s\n", "¿Que desea hacer?", "1. Mostrar todos los clientes existentes y sus datos", "2. Editar algun dato de algun cliente existente", "3. Crear una cuenta para un nuevo cliente", "4. Eliminar un cliente de la lista", "5. Salir del programa"); comprobarCantidad(basedatos); switch(opcion) { case 1: mostrarClientes(basedatos); break; case 2: editarCliente(basedatos); break; case 3: crearCliente(basedatos); break; case 4: eliminarCliente(basedatos); break; case 5:break; default: printf("Opcion no correcta.\n"); break; } } while (opcion != 5); } return 0; } void mostrarClientes(FILE *fichero) { printf("Error: el fichero esta vacio.\n"); return; } printf("%-9s%-16s%-41s%s\n", "Cuenta", "Nombre", "Apellidos", "Dinero"); fread(&cliente , sizeof(struct fichaCliente ), 1, fichero ); if (cliente.cuenta != 0) { printf("%-9i%-16s%-41s%.2f", cliente. cuenta, cliente. nombre, cliente. apellidos, cliente. dinero); } } } void editarCliente(FILE *fichero) { printf("Error: el fichero esta vacio.\n"); return; } int cuenta, opcion; float temporal; printf("Introduzca el numero de cuenta del cliente: "); if (cuenta > numero_cuentas) { printf("El cliente no existe. Cree una cuenta para el.\n"); } else { fseek(fichero , sizeof(struct fichaCliente ) * (cuenta -1), SEEK_SET ); fread(&cliente , sizeof(struct fichaCliente ), 1, SEEK_SET ); if (!strcmp(cliente. nombre, "")) printf("La cuenta %i contiene un cliente vacio.\n", cuenta ); else { do { printf("Que desea modificar?\n%s\n%s\n%s\n%s\n%s\n", "1. Nombre del cliente", "2. Apellidos del cliente", "3. Dinero del cliente", "4. Añadir/quitar dinero", "5. Cancelar operacion"); switch (opcion) { case 1: printf("Introduzca el nuevo nombre del cliente: "); scanf(" %[^\n]", cliente. nombre); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 2: printf("Introduzca los nuevos apellidos del cliente: "); scanf(" %[^\n]", cliente. apellidos); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 3: printf("Introduzca la cantidad actual de dinero del cliente: "); scanf(" %f", &cliente. dinero); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 4: printf("Introduzca la cantidad de dinero a añadir/quitar (+/-): "); cliente.dinero += temporal; fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 5:break; default:printf("Opcion invalida.\n\n");break ; } } while (opcion != 5); } } } void crearCliente(FILE *fichero) { int cuenta; short i, distancia; char respuesta; printf("Introduzca el numero de cuenta que desea utilizar: "); if(cuenta > numero_cuentas) { distancia = cuenta - numero_cuentas; while(fgetc(fichero ) != EOF ); for (i = 0; i < distancia; i++) { fwrite(&clienteVacio , sizeof(struct fichaCliente ), 1, fichero ); } //fseek(fichero, sizeof(struct fichaCliente) * (cuenta-1), SEEK_SET); asistenteCreacionCliente(cuenta); cliente.cuenta = cuenta; fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); } else { fseek(fichero , sizeof(struct fichaCliente ) * (cuenta -1), SEEK_SET ); fread(&cliente , sizeof(struct fichaCliente ), 1, fichero ); if (cliente.cuenta == 0) { asistenteCreacionCliente(cuenta); cliente.cuenta = cuenta; fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); } else { printf("¡El numero de cuenta ya contiene un cliente! ¿Desea continuar? (s/n) "); do { switch (respuesta) { case 's': asistenteCreacionCliente(cuenta); cliente.cuenta = cuenta; fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 'n':break; default: printf("Opcion incorrecta.\n"); } } while (respuesta != 'n' && respuesta != 's'); } } } void eliminarCliente(FILE *fichero) { printf("Error: el fichero esta vacio.\n"); return; } int cuenta; printf("Introduzca el numero de cuenta a eliminar: "); if(cuenta > numero_cuentas) { printf("Error: el cliente con el numero de cuenta %i no existe.\n", cuenta ); } else { fseek(fichero , sizeof(struct fichaCliente ) * (cuenta -1), SEEK_SET ); fwrite(&clienteVacio , sizeof(struct fichaCliente ), 1, fichero ); printf("El cliente %i ha sido eliminado satisfactoriamente.\n", cuenta ); } } void comprobarCantidad(FILE *fichero) { fread(&cliente , sizeof(struct fichaCliente ), 1, fichero ); numero_cuentas++; } } void asistenteCreacionCliente(int cuenta) { char correcto; do { printf("Introduzca el nombre del cliente con cuenta %i: ", cuenta ); scanf(" %[^\n]", cliente. nombre); printf("Introduzca los apellidos del cliente con cuenta %i: ", cuenta ); scanf(" %[^\n]", cliente. apellidos); printf("Introduzca la cantidad de dinero que el cliente con numero de cuenta %i posee: ", cuenta ); scanf(" %f", &cliente. dinero); if (strcmp(cliente. nombre, " ") == 0 && strcmp(cliente. apellidos, " ") == 0) correcto = 'n'; else correcto = 's'; if (correcto == 'n') printf("Los datos introducidos no son validos.\n"); } while (correcto == 'n'); }
|
|
|
En línea
|
|
|
|
TheWarriorVicent
Desconectado
Mensajes: 3
|
Resubo el código, le he conseguido hacer unas cuantas mejoras: #include <stdio.h> #include <string.h> struct fichaCliente { // tamaño: 68 bits int cuenta; char nombre[15], apellidos[45]; float dinero; } cliente, clienteVacio = {0, "", "", 0.0}; short numero_cuentas = 0; void mostrarClientes(FILE *); void editarCliente(FILE *); void crearCliente(FILE *); void eliminarCliente(FILE *); void comprobarCantidad(FILE *); void asistenteCreacionCliente(int); int main() { int opcion; FILE *basedatos; if (!(basedatos = fopen("base_de_datos.dat", "a+"))) perror("No se ha podido abrir el fichero.\n"); else { do { printf("%s\n%s\n%s\n%s\n%s\n%s\n", "¿Que desea hacer?", "1. Mostrar todos los clientes existentes y sus datos", "2. Editar algun dato de algun cliente existente", "3. Crear una cuenta para un nuevo cliente", "4. Eliminar un cliente de la lista", "5. Salir del programa"); comprobarCantidad(basedatos); printf("%i\n", numero_cuentas ); switch(opcion) { case 1: mostrarClientes(basedatos); break; case 2: editarCliente(basedatos); break; case 3: crearCliente(basedatos); break; case 4: eliminarCliente(basedatos); break; case 5:break; default: printf("Opcion no correcta.\n"); break; } } while (opcion != 5); } return 0; } void mostrarClientes(FILE *fichero) { if (fgetc(fichero ) == EOF ) { printf("Error: el fichero esta vacio.\n"); return; } printf("\n%-9s%-16s%-41s%s\n", "Cuenta", "Nombre", "Apellidos", "Dinero"); do { fread(&cliente , sizeof(struct fichaCliente ), 1, fichero ); if (feof(fichero )) // si se omite esto imprimira la ultima cuenta dos veces if (cliente.cuenta != 0) { printf("%-9i%-16s%-41s%.2f", cliente. cuenta, cliente. nombre, cliente. apellidos, cliente. dinero); } } void editarCliente(FILE *fichero) { if (fgetc(fichero ) == EOF ) { printf("Error: el fichero esta vacio.\n"); return; } //rewind(fichero); <-- innecesario int cuenta, opcion; float temporal; printf("Introduzca el numero de cuenta del cliente: "); if (cuenta > numero_cuentas) { printf("El cliente no existe. Cree una cuenta para el.\n"); } else { fseek(fichero , sizeof(struct fichaCliente ) * (cuenta -1), SEEK_SET ); fread(&cliente , sizeof(struct fichaCliente ), 1, SEEK_SET ); if (!strcmp(cliente. nombre, "")) printf("La cuenta %i contiene un cliente vacio.\n", cuenta ); else { do { printf("Que desea modificar?\n%s\n%s\n%s\n%s\n%s\n", "1. Nombre del cliente", "2. Apellidos del cliente", "3. Dinero del cliente", "4. Añadir/quitar dinero", "5. Cancelar operacion"); switch (opcion) { case 1: printf("Introduzca el nuevo nombre del cliente: "); scanf(" %[^\n]", cliente. nombre); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 2: printf("Introduzca los nuevos apellidos del cliente: "); scanf(" %[^\n]", cliente. apellidos); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 3: printf("Introduzca la cantidad actual de dinero del cliente: "); scanf(" %f", &cliente. dinero); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 4: printf("Introduzca la cantidad de dinero a añadir/quitar (+/-): "); cliente.dinero += temporal; fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 5:break; default:printf("Opcion invalida.\n\n");break ; } } while (opcion != 5); } } } void crearCliente(FILE *fichero) { int cuenta; short i, distancia; char respuesta; printf("Introduzca el numero de cuenta que desea utilizar: "); if(cuenta > numero_cuentas) { distancia = cuenta - numero_cuentas; fseek(fichero , sizeof(struct fichaCliente ) * numero_cuentas , SEEK_SET ); for (i = 1; i < distancia; i++) { // antiguo enunciado: for (i = 0; i < distancia; i++); error: i = 0 fwrite(&clienteVacio , sizeof(struct fichaCliente ), 1, fichero ); } //fseek(fichero, sizeof(struct fichaCliente) * (cuenta-1), SEEK_SET); asistenteCreacionCliente(cuenta); cliente.cuenta = cuenta; fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); } else { fseek(fichero , sizeof(struct fichaCliente ) * (cuenta -1), SEEK_SET ); fread(&cliente , sizeof(struct fichaCliente ), 1, fichero ); if (cliente.cuenta == 0) { asistenteCreacionCliente(cuenta); cliente.cuenta = cuenta; fseek(fichero , sizeof(struct fichaCliente ) * (cuenta - 1), SEEK_SET ); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); } else { printf("¡El numero de cuenta ya contiene un cliente! ¿Desea continuar? (s/n) "); do { switch (respuesta) { case 's': asistenteCreacionCliente(cuenta); cliente.cuenta = cuenta; fseek(fichero , sizeof(struct fichaCliente ) * (cuenta - 1), SEEK_SET ); fwrite(&cliente , sizeof(struct fichaCliente ), 1, fichero ); break; case 'n':break; default: printf("Opcion incorrecta.\n"); } } while (respuesta != 'n' && respuesta != 's'); } } } void eliminarCliente(FILE *fichero) { if (fgetc(fichero ) == EOF ) { printf("Error: el fichero esta vacio.\n"); return; } int cuenta; printf("Introduzca el numero de cuenta a eliminar: "); if(cuenta > numero_cuentas) { printf("Error: el cliente con el numero de cuenta %i no existe.\n", cuenta ); } else { fseek(fichero , sizeof(struct fichaCliente ) * (cuenta -1), SEEK_SET ); fwrite(&clienteVacio , sizeof(struct fichaCliente ), 1, fichero ); printf("El cliente %i ha sido eliminado satisfactoriamente.\n", cuenta ); } } void comprobarCantidad(FILE *fichero) { if (fgetc(fichero ) == EOF ) return; numero_cuentas = 0; do { fread(&cliente , sizeof(struct fichaCliente ), 1, fichero ); if (feof(fichero )) numero_cuentas ++; // si se hace directamente numero_cuentas++ no funcionara correctamente } void asistenteCreacionCliente(int cuenta) { char correcto; do { printf("Introduzca el nombre del cliente con cuenta %i: ", cuenta ); scanf(" %[^\n]", cliente. nombre); printf("Introduzca los apellidos del cliente con cuenta %i: ", cuenta ); scanf(" %[^\n]", cliente. apellidos); printf("Introduzca la cantidad de dinero que el cliente con numero de cuenta %i posee: ", cuenta ); scanf(" %f", &cliente. dinero); if (strcmp(cliente. nombre, " ") == 0 && strcmp(cliente. apellidos, " ") == 0) correcto = 'n'; else correcto = 's'; if (correcto == 'n') printf("Los datos introducidos no son validos.\n"); } while (correcto == 'n'); }
Ahora los problemas que me presenta son los siguientes: -Sigue sin eliminar las cuentas correctamente. -No crea bien las cuentas (prueben a crear una cuenta y otra con un numero de cuenta mayor y muestrenlas). -No edita bien las cuentas tampoco.
|
|
|
En línea
|
|
|
|
TheWarriorVicent
Desconectado
Mensajes: 3
|
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: #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'; do { if(fread(&cliente ,sizeof(struct fCliente ), 1, fichero )) numero_cuentas++; if (cliente.cuenta > 0) numero_cuentas_no_vacias++; //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: 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 ); } 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 ); 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 ); } } } } 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 ); break; case 5:break; default:printf("Error: opcion incorrecta.\n\n"); } } while (opcion != 5); return 0; }
|
|
|
En línea
|
|
|
|
|
Mensajes similares |
|
Asunto |
Iniciado por |
Respuestas |
Vistas |
Último mensaje |
|
|
Acceso directo
Programación Visual Basic
|
xDie
|
3
|
2,596
|
7 Noviembre 2006, 19:38 pm
por CeLaYa
|
|
|
crear acceso directo...
Programación Visual Basic
|
soru13
|
1
|
2,106
|
28 Diciembre 2006, 03:19 am
por CeLaYa
|
|
|
Crear acceso directo
Programación Visual Basic
|
Jareth
|
0
|
1,618
|
13 Mayo 2007, 23:39 pm
por Jareth
|
|
|
manejo de archivos de acceso directo en C++
Programación C/C++
|
aryel_1203
|
1
|
3,122
|
13 Diciembre 2016, 13:45 pm
por ivancea96
|
|
|
[Abril Negro] Unir Archivos Exe,Vbs y Bat a Un Acceso Directo lnk
Scripting
|
Flamer
|
1
|
4,111
|
17 Marzo 2018, 12:44 pm
por Borito30
|
|