tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero

Iniciado por Darkestnazgul, 28 Diciembre 2015, 19:14 PM

0 Miembros y 1 Visitante están viendo este tema.

Darkestnazgul

alguien que pueda revisar mi codigo y ayudarme. esta en c y lo que necesito es que modifique bien y borre contacvtos del fichero solo que no se como hacerlo trate usando un fseek pero no se que hacer bien xc

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct{
   char nombre [35];
   char mail [25];
   int telefono;
}Contacto;

void menu (char* nombreArchivo);
Contacto crearContacto();
void guardarContacto(Contacto contacto, char* nombreArchivo);
void mostrarAgenda(char* nombreArchivo);
void borrarContacto(Contacto contacto, char* nombreArchivo);
void modificarContacto(Contacto contacto,char* nombreArchivo);
void pausar();
int i,buscar=0;
int main(){
   char nombreArchivo[12]="agenda.bin";
   
   menu (nombreArchivo);
      
}
void menu (char* nombreArchivo){
   int opcion;
   do{
      
      system ("cls");
      printf("1. Crear contacto:\n");
      printf("2.Consultar agenda:\n");
      printf("3.borrar contacto:\n");
      printf("4.Modificar contacto:\n");
      printf("5.salir:\n\n");
      printf("ingresa una opcion: ");
      scanf(" %d",&opcion);
      if (opcion>0 && opcion < 6){
         system("cls");
         switch (opcion){
            case 1:
               guardarContacto(crearContacto(),nombreArchivo);
               break;
            case 2:
               mostrarAgenda (nombreArchivo);
               break;
            case 3:
               borrarContacto(Contacto(),nombreArchivo);
               break;
            case 4:
               modificarContacto(Contacto(),nombreArchivo);
            case 5:
               printf("fin del programa \n");
               //pausar();
               break;
               
            
         }
      }
      else {
         printf("\nOpcion no contemplada\n");
         pausar ();
      }
   }while (opcion!=5);
   
}
Contacto crearContacto(){
       Contacto contacto;
     
       printf("Nombre: ");
       scanf(" %[^\n]", contacto.nombre);
       printf("mail: ");
       scanf(" %[^\n]", contacto.mail);
       printf("Telefono: ");
       scanf(" %d", &contacto.telefono);
     
       return contacto;
   }

   void guardarContacto(Contacto contacto, char* nombreArchivo){
       FILE* file= fopen(nombreArchivo, "ab");
     
       if (file==NULL){
           printf("Error al intentar acceder al archivo\n");
           pausar();
       }
       else{
           fwrite(&contacto, sizeof(Contacto), 1, file);
           printf("\nContacto guardado!\n");
           pausar();
           fclose(file);
       }
   }
void mostrarAgenda(char* nombreArchivo){
       FILE* file= fopen(nombreArchivo, "rb");
       int i;
     
       if (file==NULL){
           printf("Error al intentar acceder al archivo\n");
           pausar();
       }
       else{
           Contacto contacto;
           printf("%2s %-35s %-25s %-14s\n", "ID", "Nombre", "mail", "Telefono");
           i = 0;
           while (fread(&contacto, sizeof(Contacto), 1, file)){
              i++;
               printf("%-2u %-35s %-25s %-14d\n", i, contacto.nombre, contacto.mail, contacto.telefono);
           }
           fclose(file);
           printf("\n\n");
           pausar();
       }
   }
void borrarContacto(Contacto contacto,char*nombreArchivo){
   FILE*file=  fopen(nombreArchivo,"wb");
   if (file==NULL){
      printf("no se encontro el contacto a borrar");
      pausar();
      
   }
   else {
   fwrite(&contacto,sizeof(Contacto),1,file);
      printf("\n Contacto eliminado:\n");
      pausar();
      fclose(file);
      
   }
}

void  modificarContacto(Contacto contacto, char*nombreArchivo){
   FILE*file=  fopen(nombreArchivo,"a+b");
   Contacto vec[1];


   printf("ingresa el ID de registro que deseas modificar: ");
   scanf("%i",&buscar);

   fseek(file, 100* sizeof(Contacto), SEEK_SET);
   fwrite(&vec,sizeof(Contacto),1,file);
   
   fseek(file, 100* sizeof(Contacto), SEEK_SET);
   fread(&vec,sizeof(Contacto),1,file);
   
   fgets(nombreArchivo,80,file);


   ftell(file);
   fclose(file);
}
void pausar(){
   printf("Presione ENTER para continuar");
 
   while (getchar() != '\n');
   getchar();
 
   printf("");
}

class_OpenGL

Para la próxima, pon tu código entre las etiquetas GeSHI (entre [ code=cpp] y [ /code], quitando espacios). Además, explica que errores has detectado para que así sea más fácil ayudarte...

Bien, he compilado el código para detectar errores más rápidamente, y he encontrado unos cuantos (presuponiendo que es código C):

main.c: In function 'menu':
main.c:51:31: error: expected expression before 'Contacto'
               borrarContacto(Contacto(),nombreArchivo);
                              ^
main.c:51:31: error: too few arguments to function 'borrarContacto'
main.c:15:6: note: declared here
void borrarContacto(Contacto contacto, char* nombreArchivo);
     ^
main.c:54:34: error: expected expression before 'Contacto'
               modificarContacto(Contacto(),nombreArchivo);
                                 ^
main.c:54:34: error: too few arguments to function 'modificarContacto'
main.c:16:6: note: declared here
void modificarContacto(Contacto contacto,char* nombreArchivo);
     ^
main.c: In function 'pausar':
main.c:160:5: warning: zero-length ms_printf format string [-Wformat-zero-length
]
    printf("");
    ^


Realmente, todos los errores pasan porque no tienes creada una función llamada "Contacto". A esta función, la llamas en un par de ocasiones, pero no existe!.

Realmente, no puedes crear esa función, porque has definido un tipo con ese mismo nombre.

Fuera de los errores de sintaxis, no sé si hay más errores...

_____________________________

PD.: Yo he presupuesto que el código está en C, pero si lo estás haciendo en C++, puedes hacerlo MUCHO más óptimo (por ejemplo, pasando por referencia los argumentos).

Si fuera C++, he compilado el código, y me sale un Warning. Quitando eso, el programa me ha funcionado bien hasta que he decidido modificar un contacto... Sinceramente, no comprendo muy bien que intención o de que forma pretendías modificar contactos... Primero, escaneas la ID del contacto, pero después no usas esa ID. En la opción borrar contacto, eliminas todos los contactos!

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

Darkestnazgul

#2
esta en C el codigo y pues se supone que debe de modificar y dar debaja datos etc por el momento solo da de alta y muestra el contacto y pues todo lo que necesito que haga ahora es modificar los registros y poder borrar uno eso se hace con fseek() no??


MAFUS

Muy buenas.

He intentado acabar el programa que has realizado y me he encontrado con el problema de que a la hora de borrar registros el archivo queda con registros vacíos, pero su tamaño es igual al momento en que tenía un mayor número de éstos.

Es decir, si se han realizado cuatro entradas, pero se han borrado tres de ellas, al archivo solo le queda una, pero sigue manteniendo un tamaño de cuatro entradas. Eso es por el hecho de que C, en su biblioteca estándar no tiene capacidad para redimensionar un archivo. Debería para ello usarse otro archivo temporal para que se incluyeran las entradas válidas o usar funciones del S.O. para redimensionar el archivo.

Trabajar todo directamente sobre el archivo, como pretendes, complica un poco las cosas.  :-\

class_OpenGL


Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

MAFUS

Sí, pero viendo que en todo momento trabaja directamente con el archivo he creído que esa es una premisa de su problema. Ya he visto otros enunciados por aquí, en el foro, que dicen que se debe trabajar directamente con el archivo.

Darkestnazgul

entonces que deberia hacer XD soy todavia un nobato xc en especial en esto de los ficheros

MAFUS

Una idea sería que hicieras todo el trabajo en la memoria, tal vez usando listas enlazadas. Al principio del programa miras si el archivo de la agenda existe. Llenas la lista con los datos del archivo si hay. Con todas tus opciones trabajas sobre la lista en memoria, y añades una función para guardarlo todo en el disco.
También puedes añadir una funcionalidad en salir del programa para preguntar al usuario si desea guardar los cambios.

MAFUS

Muy buenas.

Pues tu programa, algo modificado para poder borrar y editar registros quedaria mas o menos como se muestra a continuacion. Se puede y, de hecho, se debe mejorar. Como ha comentado class_OpenGL deberias hacer que trabajara con una copia en memoria para trabajar con ella y el resultado volcarlo despues en el archivo. La modificacion es sustancial.

Sin mas demora aqui va tu programa medianamente funcional. Repasalo, intenta entender porque se hace cada cosa. Esta enteramente basado en funciones de libreria estandar. No encontraras problemas en seguirlo.


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef _WIN32
#define CLSCR "cls"
#else
#define CLSCR "clear"
#endif

typedef struct {
   char nombre[35];
   char mail[25];
   char telefono[14];
} Contacto;

const char* nombreArchivo = "agenda.bin";

void menu();
Contacto crearContacto();
void guardarContacto();
void mostrarAgenda();
void borrarContacto();
void modificarContacto();
void pausar();

int main() {
   menu();

   return 0;
}

void menu() {
   int opcion;

   do {
       system(CLSCR);
       printf("MENU PRINCIPAL\n");
       printf("==============\n\n");
       printf("1. Crear contacto\n");
       printf("2. Consultar agenda\n");
       printf("3. Borrar contacto\n");
       printf("4. Modificar contacto\n");
       printf("5. Salir\n\n");
       printf("Ingresa una opcion: ");
       scanf("%d", &opcion);
       while(getchar() != '\n');
       
       if (opcion > 0 && opcion < 6) {
           switch (opcion) {
               case 1:
                   guardarContacto();
                   break;
               case 2:
                   mostrarAgenda();
                   break;
               case 3:
                   borrarContacto();
                   break;
               case 4:
                   modificarContacto();
                   break;
               case 5:
                   printf("Fin del programa\n");
                   pausar();
                   break;
           }
       }
       else {
           printf("\nOpcion no contemplada\n");
           pausar();
       }
   } while (opcion != 5);
}

Contacto crearContacto() {
   Contacto contacto;
   
   memset(&contacto, 0, sizeof(Contacto));
   
   system(CLSCR);
   printf("NUEVO CONTACTO\n");
   printf("==============\n\n");
   
   printf("Nombre: ");
   fgets(contacto.nombre, sizeof(contacto.nombre), stdin);
   contacto.nombre[strlen(contacto.nombre) - 1] = '\0';
   printf("Correo-e: ");
   fgets(contacto.mail, sizeof(contacto.mail), stdin);
   contacto.mail[strlen(contacto.mail) - 1] = '\0';
   printf("Telefono: ");
    fgets(contacto.telefono, sizeof(contacto.telefono), stdin);
    contacto.telefono[strlen(contacto.telefono) - 1] = '\0';
   
   return contacto;
}

void guardarContacto() {
   FILE *file;
   Contacto contacto;
   long int fcur; // Actual posicion dentro del archivo
   long int fend; // Posicion de final de archivo
   char c; // Caracter adquirido
   
   file = fopen(nombreArchivo, "rb"); // Miro si el archivo existe
   if(file == NULL) { // No existe
       file = fopen(nombreArchivo, "w+b"); // Pues lo abro nuevo
       if(file == NULL) { // No se ha podido crear
           printf("No se ha podido generar un archivo para la agenda\n");
           pausar();
       }
       else { // Si se ha podido crear. Guardo el primer registro
           contacto = crearContacto();
           fwrite(&contacto, sizeof(contacto), 1, file);
           fclose(file);
       }
   }
   else { // Existe el archivo. Busco en el un registro vacio
       c = fgetc(file);
       if(c == '\0') {
           ungetc(c, file);
           fcur = ftell(file); // Encontrado en el primer registro
       }
       else {
           fseek(file, 0, SEEK_END);
           fend = ftell(file);
           fseek(file, 0, SEEK_SET);
           while((c = fgetc(file)) != '\0' && ftell(file) < fend) {
               ungetc(c, file);
               fseek(file, sizeof(Contacto), SEEK_CUR);
           }
           ungetc(c, file);
           fcur = ftell(file); // Encontrado en posteriores registros
           fclose(file);
           if(fcur == fend) { // Si no hay registros vacios
               file = fopen(nombreArchivo, "ab");
               if(file == NULL) {
                   printf("No se ha podido generar un archivo para la agenda\n");
                   pausar();
               }
               else {
                   contacto = crearContacto();
                   fwrite(&contacto, sizeof(contacto), 1, file); // Anado mi registro al final
                   fclose(file);
               }
           }
           else {
               file = fopen(nombreArchivo, "r+b");
               if(file == NULL) {
                   printf("No se ha podido generar un archivo para la agenda\n");
                   pausar();
               }
               else {
                   fseek(file, fcur, SEEK_SET);
                   contacto = crearContacto();
                   fwrite(&contacto, sizeof(contacto), 1, file); // Si habia vacio lo guardo en el
                   fclose(file);
               }
           }
       }
   }
}

void mostrarAgenda() {
   FILE* file = fopen(nombreArchivo, "rb");
   Contacto contacto;
   int i;
   
   system(CLSCR);
   printf("CONTACTOS\n");
   printf("=========\n\n");
   
   if(file == NULL) {
       printf("Error al intentar acceder al archivo\n");
   }
   else {
       printf("%s %-35s %-25s %-14s\n", "ID", "Nombre", "Correo-e", "Telefono");
       for(i = 0; i < 3+36+26+14; ++i)
           putchar('-');
       putchar('\n');
       i = 0;
       while (fread(&contacto, sizeof(Contacto), 1, file)) {
           i++;
           printf("%-2u %-35s %-25s %-14s\n", i, contacto.nombre, contacto.mail, contacto.telefono);
       }
       fclose(file);
       printf("\n");
   }
   pausar();
}

void borrarContacto() {
   FILE *file = fopen(nombreArchivo, "r+b");
   Contacto vacio;
   int buscar;
   
   memset(&vacio, 0, sizeof(Contacto));
   
   system(CLSCR);
   printf("BORRAR UN CONTACTO\n");
   printf("==================\n\n");
   
   if(file != NULL)
   {
       printf("Ingresa el ID de registro que deseas borrar: ");
       scanf("%i",&buscar);
       while(getchar() != '\n');
       --buscar;
       
       fseek(file, 0, SEEK_END);
       if(buscar * sizeof(Contacto) <= ftell(file))
       {
           fseek(file, buscar * sizeof(Contacto), SEEK_SET);
           fwrite(&vacio, sizeof(Contacto), 1, file);
       }
       else {
           printf("El indice proporcionado no corresponde a ninguna entrada\n\n");
       }
       fclose(file);
   }
   else {
       printf("No existe ninguna entrada en la agenda");
   }
   pausar();
}

void modificarContacto() {
   FILE *file = fopen(nombreArchivo, "r+b");
   Contacto contacto;
   int buscar;
   
   system(CLSCR);
   printf("MODIFICAR UN CONTACTO\n");
   printf("=====================\n\n");
   
   if(file != NULL) {
       printf("Ingresa el ID de registro que deseas modificar: ");
       scanf("%i",&buscar);
       while(getchar() != '\n');
       --buscar;
       
       fseek(file, 0, SEEK_END);
       if(buscar * sizeof(Contacto) <= ftell(file))
       {
           contacto = crearContacto();
           fseek(file, buscar * sizeof(Contacto), SEEK_SET);
           fwrite(&contacto, sizeof(Contacto), 1, file);
       }
       else {
           printf("El indice proporcionado no corresponde a ninguna entrada\n\n");
       }
       fclose(file);
   }
   else {
       printf("No existe ninguna entrada en la agenda\n\n");
   }
   pausar();
}

void pausar() {
   char c;
   
   printf("Presione ENTER para continuar...");
   while ((c = getchar()) != '\n');
}