Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - TheWarriorVicent

#1
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';

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;
}
#2
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");

fflush(stdin);
scanf(" %i", &opcion);

rewind(basedatos);
comprobarCantidad(basedatos);
rewind(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;
}

putchar('\n');
} while (opcion != 5);

}

fclose(basedatos);
return 0;
}

void mostrarClientes(FILE *fichero) {
if (fgetc(fichero) == EOF) {
printf("Error: el fichero esta vacio.\n");
return;
}

rewind(fichero);

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);
putchar('\n');
}
} while(!feof(fichero));
}

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: ");
fflush(stdin);
scanf(" %i", &cuenta);

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");
fflush(stdin);
scanf(" %i", &opcion);

switch (opcion) {
case 1:
printf("Introduzca el nuevo nombre del cliente: ");
fflush(stdin);
scanf(" %[^\n]", cliente.nombre);
fwrite(&cliente, sizeof(struct fichaCliente), 1, fichero);
break;

case 2:
printf("Introduzca los nuevos apellidos del cliente: ");
fflush(stdin);
scanf(" %[^\n]", cliente.apellidos);
fwrite(&cliente, sizeof(struct fichaCliente), 1, fichero);
break;

case 3:
printf("Introduzca la cantidad actual de dinero del cliente: ");
fflush(stdin);
scanf(" %f", &cliente.dinero);
fwrite(&cliente, sizeof(struct fichaCliente), 1, fichero);
break;

case 4:
printf("Introduzca la cantidad de dinero a añadir/quitar (+/-): ");
fflush(stdin);
scanf(" %f", &temporal);
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: ");
fflush(stdin);
scanf(" %i", &cuenta);

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 {
fflush(stdin);
respuesta = getchar();

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: ");
fflush(stdin);
scanf(" %i", &cuenta);

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;

rewind(fichero);

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
} while(!feof(fichero));
}

void asistenteCreacionCliente(int cuenta) {
char correcto;
do {
printf("Introduzca el nombre del cliente con cuenta %i: ", cuenta);
fflush(stdin);
scanf(" %[^\n]", cliente.nombre);

printf("Introduzca los apellidos del cliente con cuenta %i: ", cuenta);
fflush(stdin);
scanf(" %[^\n]", cliente.apellidos);

printf("Introduzca la cantidad de dinero que el cliente con numero de cuenta %i posee: ", cuenta);
fflush(stdin);
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.
#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");

fflush(stdin);
scanf(" %i", &opcion);

rewind(basedatos);
comprobarCantidad(basedatos);
rewind(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;
}

putchar('\n');
} while (opcion != 5);

}

fclose(basedatos);
return 0;
}

void mostrarClientes(FILE *fichero) {
if (feof(fichero)) {
printf("Error: el fichero esta vacio.\n");
return;
}

printf("%-9s%-16s%-41s%s\n", "Cuenta", "Nombre", "Apellidos", "Dinero");
while(!feof(fichero)) {
fread(&cliente, sizeof(struct fichaCliente), 1, fichero);
if (cliente.cuenta != 0) {
printf("%-9i%-16s%-41s%.2f", cliente.cuenta, cliente.nombre, cliente.apellidos, cliente.dinero);
putchar('\n');
}
}
}

void editarCliente(FILE *fichero) {
if (feof(fichero)) {
printf("Error: el fichero esta vacio.\n");
return;
}

int cuenta, opcion;
float temporal;

printf("Introduzca el numero de cuenta del cliente: ");
fflush(stdin);
scanf(" %i", &cuenta);

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");
fflush(stdin);
scanf(" %i", &opcion);

switch (opcion) {
case 1:
printf("Introduzca el nuevo nombre del cliente: ");
fflush(stdin);
scanf(" %[^\n]", cliente.nombre);
fwrite(&cliente, sizeof(struct fichaCliente), 1, fichero);
break;

case 2:
printf("Introduzca los nuevos apellidos del cliente: ");
fflush(stdin);
scanf(" %[^\n]", cliente.apellidos);
fwrite(&cliente, sizeof(struct fichaCliente), 1, fichero);
break;

case 3:
printf("Introduzca la cantidad actual de dinero del cliente: ");
fflush(stdin);
scanf(" %f", &cliente.dinero);
fwrite(&cliente, sizeof(struct fichaCliente), 1, fichero);
break;

case 4:
printf("Introduzca la cantidad de dinero a añadir/quitar (+/-): ");
fflush(stdin);
scanf(" %f", &temporal);
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: ");
fflush(stdin);
scanf(" %i", &cuenta);

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 {
fflush(stdin);
respuesta = getchar();

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) {
if (feof(fichero)) {
printf("Error: el fichero esta vacio.\n");
return;
}

int cuenta;
printf("Introduzca el numero de cuenta a eliminar: ");
fflush(stdin);
scanf(" %i", &cuenta);

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) {
while(!feof(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);
fflush(stdin);
scanf(" %[^\n]", cliente.nombre);

printf("Introduzca los apellidos del cliente con cuenta %i: ", cuenta);
fflush(stdin);
scanf(" %[^\n]", cliente.apellidos);

printf("Introduzca la cantidad de dinero que el cliente con numero de cuenta %i posee: ", cuenta);
fflush(stdin);
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');
}