Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Darkestnazgul en 28 Diciembre 2015, 19:14 pm



Título: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: Darkestnazgul en 28 Diciembre 2015, 19:14 pm
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("");
}


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: class_OpenGL en 28 Diciembre 2015, 21:28 pm
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):

Código:
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!


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: Darkestnazgul en 29 Diciembre 2015, 00:09 am
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??



Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: MAFUS en 29 Diciembre 2015, 00:57 am
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.  :-\


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: class_OpenGL en 29 Diciembre 2015, 01:00 am
MAFUS - O podrías cargar el archivo en memoria, y después reescribir el archivo


Prueba con el siguiente enlace:
https://foro.elhacker.net/programacion_cc/crear_un_el_archivo_ya_existe_iquestdesea_sobreescribir-t104017.0.html;msg483023


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: MAFUS en 29 Diciembre 2015, 01:07 am
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.


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: Darkestnazgul en 29 Diciembre 2015, 01:28 am
entonces que deberia hacer XD soy todavia un nobato xc en especial en esto de los ficheros


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: MAFUS en 29 Diciembre 2015, 02:17 am
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.


Título: Re: tengo problemas con mi programa no puedo modificar ni eliminar datos del fichero
Publicado por: MAFUS en 29 Diciembre 2015, 12:11 pm
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.

Código
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. #ifdef _WIN32
  6. #define CLSCR "cls"
  7. #else
  8. #define CLSCR "clear"
  9. #endif
  10.  
  11. typedef struct {
  12.    char nombre[35];
  13.    char mail[25];
  14.    char telefono[14];
  15. } Contacto;
  16.  
  17. const char* nombreArchivo = "agenda.bin";
  18.  
  19. void menu();
  20. Contacto crearContacto();
  21. void guardarContacto();
  22. void mostrarAgenda();
  23. void borrarContacto();
  24. void modificarContacto();
  25. void pausar();
  26.  
  27. int main() {
  28.    menu();
  29.  
  30.    return 0;
  31. }
  32.  
  33. void menu() {
  34.    int opcion;
  35.  
  36.    do {
  37.        system(CLSCR);
  38.        printf("MENU PRINCIPAL\n");
  39.        printf("==============\n\n");
  40.        printf("1. Crear contacto\n");
  41.        printf("2. Consultar agenda\n");
  42.        printf("3. Borrar contacto\n");
  43.        printf("4. Modificar contacto\n");
  44.        printf("5. Salir\n\n");
  45.        printf("Ingresa una opcion: ");
  46.        scanf("%d", &opcion);
  47.        while(getchar() != '\n');
  48.  
  49.        if (opcion > 0 && opcion < 6) {
  50.            switch (opcion) {
  51.                case 1:
  52.                    guardarContacto();
  53.                    break;
  54.                case 2:
  55.                    mostrarAgenda();
  56.                    break;
  57.                case 3:
  58.                    borrarContacto();
  59.                    break;
  60.                case 4:
  61.                    modificarContacto();
  62.                    break;
  63.                case 5:
  64.                    printf("Fin del programa\n");
  65.                    pausar();
  66.                    break;
  67.            }
  68.        }
  69.        else {
  70.            printf("\nOpcion no contemplada\n");
  71.            pausar();
  72.        }
  73.    } while (opcion != 5);
  74. }
  75.  
  76. Contacto crearContacto() {
  77.    Contacto contacto;
  78.  
  79.    memset(&contacto, 0, sizeof(Contacto));
  80.  
  81.    system(CLSCR);
  82.    printf("NUEVO CONTACTO\n");
  83.    printf("==============\n\n");
  84.  
  85.    printf("Nombre: ");
  86.    fgets(contacto.nombre, sizeof(contacto.nombre), stdin);
  87.    contacto.nombre[strlen(contacto.nombre) - 1] = '\0';
  88.    printf("Correo-e: ");
  89.    fgets(contacto.mail, sizeof(contacto.mail), stdin);
  90.    contacto.mail[strlen(contacto.mail) - 1] = '\0';
  91.    printf("Telefono: ");
  92.    fgets(contacto.telefono, sizeof(contacto.telefono), stdin);
  93.    contacto.telefono[strlen(contacto.telefono) - 1] = '\0';
  94.  
  95.    return contacto;
  96. }
  97.  
  98. void guardarContacto() {
  99.    FILE *file;
  100.    Contacto contacto;
  101.    long int fcur; // Actual posicion dentro del archivo
  102.    long int fend; // Posicion de final de archivo
  103.    char c; // Caracter adquirido
  104.  
  105.    file = fopen(nombreArchivo, "rb"); // Miro si el archivo existe
  106.    if(file == NULL) { // No existe
  107.        file = fopen(nombreArchivo, "w+b"); // Pues lo abro nuevo
  108.        if(file == NULL) { // No se ha podido crear
  109.            printf("No se ha podido generar un archivo para la agenda\n");
  110.            pausar();
  111.        }
  112.        else { // Si se ha podido crear. Guardo el primer registro
  113.            contacto = crearContacto();
  114.            fwrite(&contacto, sizeof(contacto), 1, file);
  115.            fclose(file);
  116.        }
  117.    }
  118.    else { // Existe el archivo. Busco en el un registro vacio
  119.        c = fgetc(file);
  120.        if(c == '\0') {
  121.            ungetc(c, file);
  122.            fcur = ftell(file); // Encontrado en el primer registro
  123.        }
  124.        else {
  125.            fseek(file, 0, SEEK_END);
  126.            fend = ftell(file);
  127.            fseek(file, 0, SEEK_SET);
  128.            while((c = fgetc(file)) != '\0' && ftell(file) < fend) {
  129.                ungetc(c, file);
  130.                fseek(file, sizeof(Contacto), SEEK_CUR);
  131.            }
  132.            ungetc(c, file);
  133.            fcur = ftell(file); // Encontrado en posteriores registros
  134.            fclose(file);
  135.            if(fcur == fend) { // Si no hay registros vacios
  136.                file = fopen(nombreArchivo, "ab");
  137.                if(file == NULL) {
  138.                    printf("No se ha podido generar un archivo para la agenda\n");
  139.                    pausar();
  140.                }
  141.                else {
  142.                    contacto = crearContacto();
  143.                    fwrite(&contacto, sizeof(contacto), 1, file); // Anado mi registro al final
  144.                    fclose(file);
  145.                }
  146.            }
  147.            else {
  148.                file = fopen(nombreArchivo, "r+b");
  149.                if(file == NULL) {
  150.                    printf("No se ha podido generar un archivo para la agenda\n");
  151.                    pausar();
  152.                }
  153.                else {
  154.                    fseek(file, fcur, SEEK_SET);
  155.                    contacto = crearContacto();
  156.                    fwrite(&contacto, sizeof(contacto), 1, file); // Si habia vacio lo guardo en el
  157.                    fclose(file);
  158.                }
  159.            }
  160.        }
  161.    }
  162. }
  163.  
  164. void mostrarAgenda() {
  165.    FILE* file = fopen(nombreArchivo, "rb");
  166.    Contacto contacto;
  167.    int i;
  168.  
  169.    system(CLSCR);
  170.    printf("CONTACTOS\n");
  171.    printf("=========\n\n");
  172.  
  173.    if(file == NULL) {
  174.        printf("Error al intentar acceder al archivo\n");
  175.    }
  176.    else {
  177.        printf("%s %-35s %-25s %-14s\n", "ID", "Nombre", "Correo-e", "Telefono");
  178.        for(i = 0; i < 3+36+26+14; ++i)
  179.            putchar('-');
  180.        putchar('\n');
  181.        i = 0;
  182.        while (fread(&contacto, sizeof(Contacto), 1, file)) {
  183.            i++;
  184.            printf("%-2u %-35s %-25s %-14s\n", i, contacto.nombre, contacto.mail, contacto.telefono);
  185.        }
  186.        fclose(file);
  187.        printf("\n");
  188.    }
  189.    pausar();
  190. }
  191.  
  192. void borrarContacto() {
  193.    FILE *file = fopen(nombreArchivo, "r+b");
  194.    Contacto vacio;
  195.    int buscar;
  196.  
  197.    memset(&vacio, 0, sizeof(Contacto));
  198.  
  199.    system(CLSCR);
  200.    printf("BORRAR UN CONTACTO\n");
  201.    printf("==================\n\n");
  202.  
  203.    if(file != NULL)
  204.    {
  205.        printf("Ingresa el ID de registro que deseas borrar: ");
  206.        scanf("%i",&buscar);
  207.        while(getchar() != '\n');
  208.        --buscar;
  209.  
  210.        fseek(file, 0, SEEK_END);
  211.        if(buscar * sizeof(Contacto) <= ftell(file))
  212.        {
  213.            fseek(file, buscar * sizeof(Contacto), SEEK_SET);
  214.            fwrite(&vacio, sizeof(Contacto), 1, file);
  215.        }
  216.        else {
  217.            printf("El indice proporcionado no corresponde a ninguna entrada\n\n");
  218.        }
  219.        fclose(file);
  220.    }
  221.    else {
  222.        printf("No existe ninguna entrada en la agenda");
  223.    }
  224.    pausar();
  225. }
  226.  
  227. void modificarContacto() {
  228.    FILE *file = fopen(nombreArchivo, "r+b");
  229.    Contacto contacto;
  230.    int buscar;
  231.  
  232.    system(CLSCR);
  233.    printf("MODIFICAR UN CONTACTO\n");
  234.    printf("=====================\n\n");
  235.  
  236.    if(file != NULL) {
  237.        printf("Ingresa el ID de registro que deseas modificar: ");
  238.        scanf("%i",&buscar);
  239.        while(getchar() != '\n');
  240.        --buscar;
  241.  
  242.        fseek(file, 0, SEEK_END);
  243.        if(buscar * sizeof(Contacto) <= ftell(file))
  244.        {
  245.            contacto = crearContacto();
  246.            fseek(file, buscar * sizeof(Contacto), SEEK_SET);
  247.            fwrite(&contacto, sizeof(Contacto), 1, file);
  248.        }
  249.        else {
  250.            printf("El indice proporcionado no corresponde a ninguna entrada\n\n");
  251.        }
  252.        fclose(file);
  253.    }
  254.    else {
  255.        printf("No existe ninguna entrada en la agenda\n\n");
  256.    }
  257.    pausar();
  258. }
  259.  
  260. void pausar() {
  261.    char c;
  262.  
  263.    printf("Presione ENTER para continuar...");
  264.    while ((c = getchar()) != '\n');
  265. }