[ Foro de C ]

Agenda-2

16-Jan-2010 11:28
emuletas yp
14 Respuestas

Bueno, sigo teniendo una duda con la agenda, que es al leer los datos. Como hago para que lea los datos de una persona que especifico?

Con scanf, obviamente, pero y luego? fscanf? Como sitúo a fscanf en los datos de la persona que yo quiero?


18-Jan-2010 14:31
emuletas yp

Ya estoy hasta las narices de la agenda :). Puede alguien pegarme el código fuente de la Agenda para que así pueda ver mejor cómo manejar ficheros por favor? Os lo ruego :'(


19-Jan-2010 22:33
emuletas yp

En serio, necesitoel código fuente. Yo no doy entendido cómo hacer el código... No sé qué debería hacer en muchas ocasiones, a?í que me gustaría verlo, no lo hago por vagancia. Si por eso fuera, no lo haría, directamente :D


20-Jan-2010 01:12
Nacho Cabanes (+32)

¿Cual de todas las versiones de la agenda necesitas? ;-)


20-Jan-2010 15:11
emuletas yp

Es esta:

Una agenda que maneje los siguientes datos: nombre, dirección, tlf móvil, email, y día, mes y año de nacimiento (estos tres últimos datos deberán ser números enteros cortos). Deberá tener capacidad para 100 fichas. Se deberá poder añadir un dato nuevo, visualizar los nombres de las fichas existentes, o mostrar todos los datos de una persona (se preguntará al usuario cual es el nombre de esa persona que quiere visualizar). Al empezar el programa, leerá los datos de un fichero llamado “agenda.dat” (si existe). Al terminar, guardará todos los datos en ese fichero.

Añado un par de cuestiones. Lo mejor del manual es que está muy bien explicado y ordenado.

Lo peor es que no incluye las soluciones de los ejercicios (deber
ía incluir las de todos).


20-Jan-2010 15:14
emuletas yp

Hey! Encontré otro manual que está muy bien tambien pero es de un nivel un poco más avanzado :D.


22-Jan-2010 02:01
Nacho Cabanes (+32)

Ah! Ok. Esa es la primera propuesta de agenda, en el apartado 6.4.

Primera pista: como debes leer todos los datos al principio y no guardarlos hasta el final, tendrás que guardarlos todos ellos en memoria, en un array de structs, como éste:

   struct
   {
       char nombre [81];
       char direccion [81];
       char tlfMovil[13];
       char email[51];
       unsigned short int diaNac, mesNac, anyoNac;
   } ficha [100];


Segunda pista: deberás leer de fichero (si existe) usando un "while (! feof(...))"

Mañana más.  ;-)


22-Jan-2010 12:14
Nacho Cabanes (+32)

Tercera pista:

El proceso de leer cada uno de los datos del fichero, comprobar que realmente se ha podido leer, quitar el \n del final... podria ser así:

fgets(linea, 80, fichero);      
if (feof(fichero)) break;  /* Si no he podido, interrumpo */
if (strlen(linea) > 0)      /* Quito el \n del final de la linea */
   linea[strlen(linea)  -1]  ='\0';
strcpy(ficha[ultimaFicha+1].nombre, linea);

...


22-Jan-2010 14:29
emuletas yp

Esto me parece ficticio. Porfavor, os he pedido el codigo fuente entero y seguido. Actualmente no quiero romperme el coco con las pistas. Es mucho mejor qu lo vea todo seguido y completo, me parece que se aprende mejor. No me vale a cachos ni con pistas.

Tengo demasiados problemas en todo el ejercicio, cada vez más. SObre todo si me presentas un ejercicio en fragmentos :(

No lo vas a hacer nunca? Te gusta ver como la gente se muere intentando hacer ejercicios? :DD


22-Jan-2010 14:51
Nacho Cabanes (+32)

Me gusta que quien quiere aprender se esfuerce en aprender :-p  (y mirando fuentes ajenos se aprende apenas un 20% que si realmente los intentas y ves en qué has fallado).

Pero bueno, por ser tú... ;-) se podría hacer asi (por ejemplo):

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

main()
{
   struct
   {
       char nombre [81];
       char direccion [81];
       char tlfMovil[13];
       char email[51];
       unsigned short int diaNac, mesNac, anyoNac;
   } ficha [100];

   FILE* fichero;        /* El fichero con los datos */
   int ultimaFicha = -1; /* Ultima ficha. Inicialmente -1 porque no hay ninguna */
   char linea[200];      /* Para leer de fichero o teclado linea a linea */
   int opcion;           /* La opcion escogida del menu */
   int i;                /* Para recorrer los datos con "for" */

   /* Abro fichero... si existe */
   fichero = fopen("agenda.dat", "rt");
   if (fichero != NULL)
   {
       puts("Leyendo datos...");
       while (! feof(fichero))
       {
           /* Intento leer cada dato, y lo guardo si lo he conseguido */
           fgets(linea, 80, fichero);      
           if (feof(fichero)) break;  /* Si no he podido, interrumpo */
           if (strlen(linea) > 0)      /* Quito el \n del final de la linea */
               linea[strlen(linea)  -1]  ='\0';
           strcpy(ficha[ultimaFicha+1].nombre, linea);

           fgets(linea, 80, fichero);      
           if (feof(fichero)) break;
           if (strlen(linea) > 0)
               linea[strlen(linea)  -1]  ='\0';
           strcpy(ficha[ultimaFicha+1].direccion, linea);

           fgets(linea, 12, fichero);      
           if (feof(fichero)) break;
           if (strlen(linea) > 0)
               linea[strlen(linea)  -1]  ='\0';
           strcpy(ficha[ultimaFicha+1].tlfMovil, linea);

           fgets(linea, 50, fichero);      
           if (feof(fichero)) break;
           if (strlen(linea) > 0)
               linea[strlen(linea)  -1]  ='\0';
           strcpy(ficha[ultimaFicha+1].email, linea);

           fgets(linea, 20, fichero);
           puts(linea);
           if (feof(fichero)) break;
           sscanf(linea, "%hd %hd %hd", &ficha[ultimaFicha+1].diaNac,
               &ficha[ultimaFicha+1].mesNac,
               &ficha[ultimaFicha+1].anyoNac);

           /* Si pude leer todo, hay una ficha mas */
           ultimaFicha ++;
       }
       fclose(fichero);
   }

   printf("Leidos %d datos", ultimaFicha+1);


   /* Parte repetitiva de manipulacion */
   do  
   {
       /* Muestro el menú y pido opciones */
       puts("\n\n  Agenda, version 0.01\n");
       puts("Elija una opcion");
       puts("1.- Nuevo dato");
       puts("2.- Ver datos existentes");
       puts("3.- Ver detalles de una persona");
       puts("0.- Terminar");

       scanf("%d", &opcion);
       getchar(); /* Absorbo la tecla "intro" */

       switch (opcion)
       {

           case 1:     /* Añadir un nuevo dato */
               puts ("Añadiendo datos...");
               printf ("Introduce nombre: ");
               gets (ficha[ultimaFicha+1].nombre);

               printf ("Introduce direccion: ");
               gets (ficha[ultimaFicha+1].direccion);

               printf ("Introduce movil: ");
               gets (ficha[ultimaFicha+1].tlfMovil);

               printf ("Introduce correo electronico: ");
               gets (ficha[ultimaFicha+1].email);

               printf ("Introduce dia de nacimiento: ");
               gets (linea);
               sscanf (linea, "%hd", &ficha[ultimaFicha+1].diaNac);

               printf ("Introduce mes de nacimiento: ");
               gets (linea);
               sscanf (linea, "%hd", &ficha[ultimaFicha+1].mesNac);

               printf ("Introduce año de nacimiento: ");
               gets (linea);
               sscanf (linea, "%hd", &ficha[ultimaFicha+1].anyoNac);

               ultimaFicha ++;
               break;


           case 2:     /* Ver todos los nombres */
               puts ("Fichas existentes:");
               for (i=0; i<=ultimaFicha; i++)
                   puts (ficha[i].nombre);
               break;


           case 3:     /* Ver todos los datos de una persona */
               printf ("Nombre a buscar? ");
               gets (linea);

               for (i=0; i<=ultimaFicha; i++)
                   if (strcmp (linea, ficha[i].nombre) == 0)
                   {
                       puts (ficha[i].nombre);
                       puts (ficha[i].direccion);
                       puts (ficha[i].tlfMovil);
                       puts (ficha[i].email);
                       printf("%hd %hd %hd\n", ficha[i].diaNac,
                           ficha[i].mesNac, ficha[i].anyoNac);
                   }
               break;                


       }

   } while (opcion != 0);



   // Finalmente, guardo los cambios
   fichero = fopen("agenda.dat", "wt");
   puts("Guardando datos...");

   for (i=0; i<=ultimaFicha; i++)
   {
       fprintf (fichero, "%s\n", ficha[i].nombre);
       fprintf (fichero, "%s\n", ficha[i].direccion);
       fprintf (fichero, "%s\n", ficha[i].tlfMovil);
       fprintf (fichero, "%s\n", ficha[i].email);
       fprintf (fichero, "%hd %hd %hd\n",
           ficha[i].diaNac, ficha[i].mesNac, ficha[i].anyoNac);
   }
   fclose(fichero);

   printf("Terminado.");
}


22-Jan-2010 15:21
emuletas yp

Gracias. GRACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASSS!!!!!!!!!!!!!!!

getchar(); /* Absorbo la tecla "intro" */

:DDDD

No absorbas teclas. Es malo parar tu salud!

:DDDD


31-Jan-2010 01:46
Nacho Cabanes (+32)


>> getchar(); /* Absorbo la tecla "intro" */

> No absorbas teclas. Es malo parar tu salud!

C es así, te hace tragar con cosas que a veces no te gustarían... ;-)


23-Jul-2010 15:25
emuletas yp

Ok, puedes explicarme esto?:

------------------------------------------------------------------

linea[strlen(linea)  -1]  ='\0';

------------------------------------------------------------------

linea[]???

strlen(linea) lo entiendo...

pero el resto no.

Si lo leo sé lo que hace, pero no entiendo bien cada parte.

Gracias


25-Jul-2010 19:10
Nacho Cabanes (+32)

Vamos con ello. Primero te pongo un ejemplo sencillo y luego contesto a tu duda sobre:

linea[strlen(linea)  -1]  ='\0';

- Como primer acercamiento:

Si la frase (vector de caracteres) llamada "linea" contiene la palabra "Hola" y haces

linea[2]  ='\0';

consigues que en la posición 2 (la tercera, porque se empieza a contar desde 0) haya un carácter nulo. Como el carácter nulo es el que indica el final, de la cadena, has conseguido que ésta pase a contener "Ho".

- Volviendo al principio: si "linea" contiene la palabra "Hola" y miras el valor de "strlen(linea)", obtendrás la longitud de esa frase (en este caso, 4).

Si lo que quisieras es quitar la última letra, tendrías que quitar el caracter 3 (esos 4 caracteres van de 0 a 3), o, en el caso general, el carácter en la posición "longitud-1".

Es decir, en el caso de la frase "Hola", quitarías la última letra con

linea[3]  ='\0';

y en un caso general, en el que tengas cualquier longitud, sería

linea[strlen(linea)  -1]  ='\0';


Por eso, el fragmento de fuente original contenía un comentario adicional, para indicar que esa orden eliminaba el último carácter de la línea (si existe):

if (strlen(linea) > 0)      /* Quito el \n del final de la linea */
   linea[strlen(linea)  -1]  ='\0';


Una forma alternativa, ligeramente más legible sería:

int longitud = strlen(linea);
if (longitud > 0)      /* Quito el \n del final de la linea */
   linea[ longitud-1 ]  ='\0';


26-Jul-2010 11:23
emuletas yp

Ok, entendido.

Gracias por la ayuda






(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.)