[ Foro de C ]

Dudas en 3a. versión de Agenda.

30-Aug-2012 16:52
Pablo Rampa
1 Respuestas

Saludos al Profesor y a los miembros del foro.
Aunque tanto el Profesor como Antonio ya me lo explicaron,
todavía tengo una duda con la agenda.
  *Si abro el archivo en el modo "ab" para agregar otra ficha,
porqué cuando lo vuelvo a abrir no aparece lo guardado.
¿Qué tengo que hacer para que lo que hay en la agenda no se borre?
Supongo que guardar todo al final en modo "wb". Lo intenté y no me resulta nada.
  *Otro problema es que se cierra el sistema al querer leer la tercera ficha.

/*6.10a_ AGENDA (3a.versión). Mejorar la última versión de la agenda anterior(6.8a, la que usa
fwrite, fread y sizeof) para que no lea todas las fichas a la vez, sino que lea una única ficha del
disco cada vez que lo necesite, saltando a la posición en que se encuentra dicha ficha con “fseek”.*/

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

int main()      
{          
  struct agenda
  {      
     char nombre [21];
     char direccion [31];
     char celular[13];
     char email[31];
     unsigned short int dia, mes, anyo;
  }persona[100];

  FILE* fichero;      
  char textoAux[21];
  int i,  numFicha, opcion, totalFichas;          
           
  do    
  {
     puts("\n\tMENU:\n");
     puts("1.- Agregar un nuevo dato.");
     puts("2.- Ver todos los datos existentes.");
     puts("3.- Ver todos los datos de una persona.");
     puts("0.- Terminar.");
     puts("   Elija una opcion: ");    
     scanf("%d", &opcion);
     getchar();                          

     switch (opcion)
     {
        case 1:    /* Agregar un nuevo dato */
           if ((fichero = fopen("gente.dat", "ab")) == NULL)
              printf("No se pudo abrir el archivo.\n");
           else
           {    
           puts("Nombre:");
           gets(persona[totalFichas].nombre);
           puts("Direccion:");
           gets(persona[totalFichas].direccion);
           puts("Celular:");
           gets(persona[totalFichas].celular);
           puts("Correo electronico:");
           gets(persona[totalFichas].email);
           printf("Dia de nacimiento: ");
           scanf("%hd", &persona[totalFichas].dia);
           printf("Mes de nacimiento: ");
           scanf("%hd", &persona[totalFichas].mes);
           printf("Anyo de nacimiento: ");
           scanf("%hd", &persona[totalFichas].anyo);
           fseek(fichero, 0, SEEK_END);
           fwrite(&persona[i], sizeof(persona), 1, fichero);
           totalFichas++;
           fclose(fichero);
           }
           break;  

       case 2:    /* Ver todos los nombres */
           
           puts ("Ver todos los nombres existentes:");
           fichero = fopen("agenda.dat", "rb");
           if (fichero != NULL)
           {
              while (! feof(fichero))
              {                          
                 fread(&persona,sizeof(persona), 1, fichero);
                 for (i=0; i<totalFichas; i++)  
                    printf("%d.- %s\n", i+1, persona[i].nombre);    
                 if (totalFichas == 0)
                 {
                    printf("No hay ningun nombre guardado.\n");
                    break;
                 }
                 else
                    if (totalFichas == 1)
                    {
                       printf("Solo hay un nombre guardado.\n");
                       break;
                    }  
                    else
                    {
                       printf("Hay %d nombres guardados.\n", totalFichas);
                       break;
                    }
              }
           }
           fclose(fichero);
           break;
               
        case 3:    /* Ver todos los datos de una persona */        
           puts("Escriba el numero del fichero a leer:\n");              
           scanf("%d", &numFicha);
           if ((numFicha >0) && (numFicha <= totalFichas))
           {        
              i=numFicha-1;
              fichero = fopen("agenda.dat", "rb");
              if (fichero != NULL)
              {    
                 fseek(fichero, sizeof(persona)*(i), SEEK_SET);
                 fread(&persona[i], sizeof(persona), 1,  fichero);
                 printf("%d.- %s %s %s %s %hd %hd %hd\n\n",
                    i+1, persona[i].nombre, persona[i].direccion,
                    persona[i].celular, persona[i].email,
                    persona[i].dia, persona[i].mes, persona[i].anyo);
              }
              fclose(fichero);
          }
          else
             printf("Escriba un numero de ficha valido.");            
          break;  
       }
       fichero = fopen("agenda.dat", "wb");  
       for (i=0; i<totalFichas; i++)
          fwrite(&persona[i], sizeof(persona), 1, fichero);
         
       fclose(fichero);            
    }
    while (opcion != 0);  
    return 0;                          
}


    .....Gracias por la atención.




31-Aug-2012 20:25
Nacho Cabanes (+83)

En el mundo real ;-) los modos "ab" suelen ser conflictivos. Su comportamiento no es igual en todos los lenguajes. Puede que no se comporte bien si no te desplazas hasta la última posición del fichero, o incluso que no se comporte bien en absoluto.

Yo te recomendaría que uses el "at" para añadir al final de un fichero de texto ya existente, "wt" para crear un fichero de texto, y "wb" para escribir en un fichero binario, sea en la posición que sea, desplazándote hasta ella con "fseek" si fuera necesario.






(No se puede continuar esta discusión porque tiene más de dos meses de antigüedad. Si tienes dudas parecidas, abre un nuevo hilo.)