Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: DickGumshoe en 7 Febrero 2012, 23:05 pm



Título: Problema en agenda con ficheros
Publicado por: DickGumshoe en 7 Febrero 2012, 23:05 pm
Hola.

Haciendo un ejercicio me he encontrado una duda.

Es este:

Código
  1. /*Una agenda que maneje los siguientes datos: nombre, dirección, tlf móvil, email, y día,
  2. mes y año de nacimiento (estos tres últimos datos deberán ser números enteros
  3. cortos). Deberá tener capacidad para 100 fichas. Se deberá poder añadir un dato
  4. nuevo, visualizar los nombres de las fichas existentes, o mostrar todos los datos de una
  5. persona (se preguntará al usuario cual es el nombre de esa persona que quiere
  6. visualizar). Al empezar el programa, leerá los datos de un fichero llamado “agenda.dat”
  7. (si existe). Al terminar, guardará todos los datos en ese fichero.*/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. int main()
  14. {
  15.    struct
  16.    {
  17.      char nombre[10];
  18.      char direccion[15];
  19.      int movil;
  20.      char email[20];
  21.      short int dia, mes, ano;
  22.    }datos[100];
  23.    char lineas[500];
  24.    FILE* fichero;
  25.    int opcion;
  26.  
  27.    fichero = fopen("agenda.dat", "rt");
  28.    if(fichero != NULL)
  29.    {
  30.  
  31.    while(! feof(fichero)) //Leemos los datos que contiene al principio
  32.    {
  33.      fgets(lineas,25,fichero);
  34.    }
  35.    fclose(fichero);
  36.  
  37.    printf("Elija una opcion\n");
  38.    printf("1. Introducir datos\n");
  39.    printf("2. Visualizar nombres de las fichas existentes\n");
  40.    printf("3. Mostrar todos los datos de una persona\n");
  41.    scanf("%d",&opcion);
  42.  
  43.    switch(opcion)
  44.    {
  45.      case 1:
  46.           //En construcción, lo editaré según las respuestas que obtenga al preguntaros.
  47.           break;
  48.      case 2:
  49.           //En construcción, lo editaré según las respuestas que obtenga al preguntaros.
  50.           break;
  51.      case 3:
  52.           //En construcción, lo editaré según las respuestas que obtenga al preguntaros.
  53.           break;
  54.      default:
  55.              printf("Opcion no valida");
  56.    }
  57.    }
  58.  
  59.  
  60.  
  61.  
  62.    system("pause");
  63.    return 0;
  64. }
  65.  
  66.  

La idea que estoy siguiendo es que primero abro el archivo en modo de lectura. Entonces pongo los casos en los que tiene que leer el archivo, y los casos en los que no. Cierro el archivo.

Después, creo un switch, en el que elijo una de las tres opciones, y ahí planteo cada cosa.

Y, finalmente, abro de nuevo el archivo, pero esta vez para escribir, y meto los datos obtenidos en el switch.

Mi problema es que no sé cómo hacer para que al cerrar el programa y volver a abrirlo sepa que ya he metido un número determinado de fichas (no sé si me explico). Creo que solo es con un do-while en el switch de "añadir datos", sumándole uno a "i", pero no estoy seguro.

También me gustaría saber si veis bien como he planteado el problema, para ver cómo puedo cambiar las cosas.

Muchísimas gracias.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: Ferno en 7 Febrero 2012, 23:11 pm
Si la idea del contador es que funcione siempre y cuando mantengas la cuenta al abrir y cerrar el programa, lo que necesitas es algún modo de almacenarlo externamente. Si usas un contador en el programa, en memoria, se borrará ese dato al cerrar el programa.
Ahora bien, puedes usar otro archivo para guardar el dato de la cantidad de fichas (supongo que al hacer este ejercicio sabes algo de manejo de archivos). Entonces, al abrir el programa, deberás leer este archivo que contiene el contador y listo, empiezas de vuelta la cuenta desde donde quedaste la última vez.

Ahora bien, no entiendo exactamente lo que quieres lograr con esto:

Código
  1. while(! feof(fichero)) //Leemos los datos que contiene al principio
  2.    {
  3.      fgets(lineas,25,fichero);
  4.    }
  5.    fclose(fichero);


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 7 Febrero 2012, 23:18 pm
Pretendo que mientras el fichero no llegue a su fin, lea todas sus líneas (pero por cómo has reaccionado, me parece que voy a tener que quitarlo, seguramente esté mal...).

No había caído en que debía almacenar el resultado de "i++" en un fichero.

Muchas gracias.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: eleon en 7 Febrero 2012, 23:26 pm
Citar
Mi problema es que no sé cómo hacer para que al cerrar el programa y volver a abrirlo sepa que ya he metido un número determinado de fichas (no sé si me explico). Creo que solo es con un do-while en el switch de "añadir datos", sumándole uno a "i", pero no estoy seguro.

Si con "cerrar al programa" te refieres a darle clic a la "cruz roja" matando el proceso, lógicamente no puedes hacer nada con variables porque se almacenan en la RAM que es una memoria volátil. En este caso debes leer el fichero y comprobar el número de contactos que hay (cada vez que leas un nombre sumas uno al contador hasta llegar al final, asi calcularás el número de elementos ya guardados).

Pero, si lo que quieres decir es después de guardar un contacto, es tan sencillo como un contador... y en el bucle que te va imprimiendo el menú pones como condición de continuación "contador < 100".

Tu código está hecho a base de librerías standard, queda feo que lo destroces con "system("pause")", aunque en general su uso no es correcto. Pon cualquier instrucción de lectura del teclado para pausar el programa.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 7 Febrero 2012, 23:32 pm
Muchas gracias a los dos. Ahora me tengo que ir ya, pero ya mañana termino el programa y dejo mi código completo.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: Ferno en 7 Febrero 2012, 23:34 pm
Pretendo que mientras el fichero no llegue a su fin, lea todas sus líneas (pero por cómo has reaccionado, me parece que voy a tener que quitarlo, seguramente esté mal...).

Jaja, no reaccioné mal, sólo preguntaba porque no entiendo el por qué de cerrar el archivo justo después de las lecturas.
Quizás dependa de lo que pretendas hacer en las 3 opciones, pero ¿No sería mejor abrir el archivo para lectura y escritura y cerrarlo antes de terminar el programa? Es decir, abrir y cerrar una única vez.


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 8 Febrero 2012, 15:18 pm
¿Entonces está bien esto?

Código
  1. while(! feof(fichero)) //Leemos los datos que contiene al principio
  2.    {
  3.      fgets(lineas,25,fichero);
  4.    }
  5.    fclose(fichero);

Lo hago por partes (me refiero a lo de abrir y cerrar el fichero para escribir/leer) porque en el manual que estoy siguiendo en la parte que hay antes del ejercicio no viene nada de cómo hacer las dos cosas (aunque he visto que viene justo después, pero bueno).

Ahora me voy a poner a terminar el programa.

Gracias.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: Ferno en 8 Febrero 2012, 15:34 pm
Mira, lo que haces con esa parte del code es leer todas las líneas, llegar al final del archivo, y después cerrarlo. Yo no le veo utilidad así como está!


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 8 Febrero 2012, 21:08 pm
¿Al cerrar el fichero "se van" los datos obtenidos con ese fgets del programa?


Título: Re: Problema en agenda con ficheros
Publicado por: do-while en 8 Febrero 2012, 21:21 pm
¡Buenas!

Supongo que la lectura/escritura en el fichero sera en binario. Si vas aumentando el tamaño del fichero segun vas metiendo datos, lo estaras haciendo de forma que añada bloques del tamaño del struct que utilizas. Por lo tanto, para saber cuantos elementos tienes en un momento dado solo tendras que calcular la longitud del fichero y dividirla por el tamaño del tipo de dato que guarda:

Código
  1.  
  2. FILE *f;
  3. unsigned long posicion, tamanio, ndatos;
  4.  
  5. f = fopen(tu_archivo,"rb");
  6.  
  7. /* las instrucciones que quieras */
  8.  
  9. /* leemos la posicion actual del fichero */
  10. posicion = ftell(f);
  11.  
  12. /* nos situamos al final del fichero */
  13. fseek(f,0,SEEK_END);
  14.  
  15. /* leemos el numero de bytes que tiene el fichero */
  16. tamanio = ftell(f);
  17.  
  18. /* volvemos a dejarlo como estaba */
  19. fseek(f,posicion,SEEK_SET);
  20.  
  21. /* si el fichero solo contiene un tipo de datos esta division siempre sera exacta */
  22. ndados = tamanio / sizeof(tu_struct);
  23.  

¡Saludos!
¡Saludos!


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 9 Febrero 2012, 15:18 pm
¡Muchas gracias, do-while!

Creo que como me lo has explicado es mejor que creando un fichero nuevo para guardar los datos.



Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 9 Febrero 2012, 19:34 pm
Me parece que tengo el programa terminado, a excepción  de un error.

Cuando pido los datos de las personas, "Introduce el nombre" e "Introduce la dirección" salen seguidos, sin que yo pueda introducir el primer dato.

Código
  1. case 1:
  2.  
  3.           printf("Introduce un nombre: ");
  4.           fgets(datos[i].nombre, 10, stdin);
  5.           printf("Introduce una direccion: ");
  6.           fgets(datos[i].direccion, 15, stdin);
  7.           printf("Introduce un movil: ");
  8.           scanf("%d",&datos[i].movil);
  9.           printf("Introduce correo electronico: ");
  10.           fgets(datos[i].email, 50, stdin);
  11.           printf("Introduce dia de nacimiento: ");
  12.           scanf("%d",&datos[i].dia);
  13.           printf("Introduce mes de nacimiento: ");
  14.           scanf("%d",&datos[i].dia);
  15.           printf("Introduce ano de nacimiento: ");
  16.           scanf("%d",&datos[i].dia);
  17.           i++;
  18.           break;

¿Cuál creéis que es mi error?

Gracias.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: do-while en 10 Febrero 2012, 04:26 am
¡Buenas!

Posiblemente hayas usado varios scanf antes de la llamada a tu funcion.

scanf deja siempre, al menos, un caracter '\n' en el buffer de entrada, y fgets lee hasta encontrar un salto de linea (que extrae del buffer de entrada). Por lo tanto lo que te pasa es que fgets esta leyendo los datos que scanf ha dejado en el buffer de entrada y por eso pasa a leer directamente el segundo dato.

Para que no te pase esto tendras que sacar toda la "basura" que te deje scanf en el buffer de entrada caracter a caracter. Incluye este codigo despues de cada scanf
Código
  1. while(getchar() != '\n');
  2.  

Otros utilizan la formula fgets + sscanf.

Yo personalmente prefieco la de getchar(), ya que no estoy dependiendo de tamaños concretos de cadenas para pasar como argumento a fgets. Pero para gustos colores.

¡Saludos!


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 10 Febrero 2012, 15:17 pm
¡Muchas gracias! Ya lo he añadido a mi código.

Por ahora tengo esto:

Código
  1. /*Una agenda que maneje los siguientes datos: nombre, dirección, tlf móvil, email, y día,
  2. mes y año de nacimiento (estos tres últimos datos deberán ser números enteros
  3. cortos). Deberá tener capacidad para 100 fichas. Se deberá poder añadir un dato
  4. nuevo, visualizar los nombres de las fichas existentes, o mostrar todos los datos de una
  5. persona (se preguntará al usuario cual es el nombre de esa persona que quiere
  6. visualizar). Al empezar el programa, leerá los datos de un fichero llamado “agenda.dat”
  7. (si existe). Al terminar, guardará todos los datos en ese fichero.*/
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12.  
  13. int main()
  14. {
  15.    struct
  16.    {
  17.      char nombre[10];
  18.      char direccion[15];
  19.      int movil;
  20.      char email[20];
  21.      short int dia, mes, ano;
  22.    }datos[100];
  23.    char lineas[500],comprobar[10];
  24.    FILE* fichero;
  25.    int opcion,posicion,tamano,i,j,aux;
  26.  
  27.    fichero = fopen("agenda.dat", "r+t");
  28.    if(fichero != NULL)
  29.    {
  30.  
  31.    while(! feof(fichero)) //Leemos los datos que contiene al principio
  32.    {
  33.      fgets(lineas,25,fichero);
  34.    }
  35.  
  36.    /*posicion actual*/
  37.    posicion = ftell(fichero);
  38.  
  39.    /* final del fichero */
  40.    fseek(fichero,0,SEEK_END);
  41.  
  42.    /* total de lineas */
  43.    tamano = ftell(fichero);
  44.  
  45.  
  46.    fseek(fichero,posicion,SEEK_SET);
  47.  
  48.    i = tamano / sizeof(datos);
  49.  
  50.    do
  51.    {
  52.    do
  53.    {
  54.    printf("Elija una opcion\n");
  55.    printf("1. Introducir datos\n");
  56.    printf("2. Visualizar nombres de las fichas existentes\n");
  57.    printf("3. Mostrar todos los datos de una persona\n");
  58.    printf("4. Salir");
  59.    scanf("%d",&opcion);
  60.  
  61.    switch(opcion)
  62.    {
  63.      case 1:
  64.  
  65.           printf("Introduce un nombre: ");
  66.           fgets(datos[i].nombre, 10, stdin);
  67.           while(getchar() != '\n');
  68.           printf("Introduce una direccion: ");
  69.           fgets(datos[i].direccion, 8, stdin);
  70.           printf("Introduce un movil: ");
  71.           scanf("%d",&datos[i].movil);
  72.           while(getchar() != '\n');
  73.           printf("Introduce correo electronico: ");
  74.           fgets(datos[i].email, 50, stdin);
  75.           printf("Introduce dia de nacimiento: ");
  76.           scanf("%d",&datos[i].dia);
  77.           while(getchar() != '\n');
  78.           printf("Introduce mes de nacimiento: ");
  79.           scanf("%d",&datos[i].mes);
  80.           while(getchar() != '\n');
  81.           printf("Introduce ano de nacimiento: ");
  82.           scanf("%d",&datos[i].ano);
  83.           i++;
  84.           break;
  85.      case 2:
  86.           for(j=0;j<=i;j++)
  87.           {
  88.             puts(datos[j].nombre);
  89.           }
  90.  
  91.  
  92.           break;
  93.      case 3:
  94.          printf("Introduce el nombre de la persona de la que desea visualizar los datos:");
  95.          fgets(comprobar, 10, stdin);
  96.  
  97.          for(j=0;j<=i;j++)
  98.          {
  99.            if(strcmp(datos[j].nombre,comprobar)==0)
  100.            {
  101.              printf("Nombre: %s\n",datos[j].nombre);
  102.              printf("Direccion: %s\n",datos[j].direccion);
  103.              printf("Movil: %d\n",datos[j].movil);
  104.              printf("Email: %s\n",datos[j].email);
  105.              printf("Dia de nacimiento: %d\n",datos[j].dia);
  106.              printf("Mes de nacimiento: %d\n",datos[j].mes);
  107.              printf("Ano de nacimiento: %d\n",datos[j].ano);
  108.            }
  109.          }
  110.           break;
  111.      case 4:
  112.           break;
  113.      default:
  114.              printf("Opcion no valida!\n");
  115.    }
  116.  
  117.    }while(opcion<1||opcion>4);
  118.    }while(opcion!=4);
  119.    }
  120.    aux=i;
  121.    for(i=0;i<=aux;i++)
  122.    {
  123.      fprintf(fichero, "%s\n", datos[i].nombre);
  124.      fprintf(fichero, "%s\n", datos[i].direccion);
  125.      fprintf(fichero, "%d\n", datos[i].movil);
  126.      fprintf(fichero, "%s\n", datos[i].email);
  127.      fprintf(fichero, "%d\n", datos[i].dia);
  128.      fprintf(fichero, "%d\n", datos[i].mes);
  129.      fprintf(fichero, "%d\n", datos[i].ano);
  130.      }
  131.   fclose(fichero);
  132.  
  133.    getchar();
  134.    printf("\n\nPulse una tecla para continuar");
  135.    getchar();
  136.    return 0;
  137. }
  138.  

¿Podríais decirme si voy bien? Ya he retirado del código "system("pause");", y lo he sustituido por getchar.

Gracias.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: do-while en 10 Febrero 2012, 15:51 pm
¡Buenas!

Esta parte del codigo esta mal (bueno, mal no esta, pero no funcionara como tu quieres):

Código
  1.           fgets(datos[i].nombre, 10, stdin);
  2.           while(getchar() != '\n');
  3.  

Te he dicho que lo de quitar caracteres de la entrada tienes que hacerlo despues de los scanf. Solo funcionara cuando la cadena introducida (contando el intro que pulses) tenga mas de 9 caracteres, ya que entonces al menos quedara un caracter en la entrada. En caso contrario, leera la cadena que introduzcas y se quedara esperando a que introduzcas mas datos para poder leerlos con getchar, por lo que perderas datos que te interesaria guardar, o a una mala, tendras que pulsar intro para que pase al siguiente mensaje solicitando datos.

Como te he dicho antes, fgets tambien extrae el caracter '\n' de la entrada, por lo tanto puedes controlar que se ha vaciado el buffer de entrada de la siguiente manera:

Código
  1. do{
  2.    fgets(cadena,10,stdin);
  3. }while(cadena[strlen(cadena) - 1] != '\n');
  4.  
Asi te aseguras de que con fgets estas leyendo todos los datos de la entrada.

Otra alternativa seria la siguiente:
Código
  1. fgets(cadena,10,stdin);
  2.  
  3. if(cadena[strlen(cadena) - 1] != '\n')
  4.    while(getchar() != '\n');
  5.  

Pero lo que te he indicado en el post anterior solo deberias utilizarlo despues de un scanf.

Otra cosa, veo que estas abriendo el fichero en modo "r+t", no se si es bueno o te puede dar datos extraños el hecho de mezclar lectura/escritura en binario al abrir un fichero en modo texto. Cuando utilices structs de un tamaño fijo, intenta utilizar siempre acceso binario a los ficheros. Asi seguro que no te llevas sorpresas con feof().

¡Saludos!


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 10 Febrero 2012, 16:18 pm
He puesto
while(getchar()!='\n');
detrás de cuando pido
Código
  1. datos[i].nombre
porque sino pasa directamente al segundo dato. Es decir, en la consola, me sale Introduce un nombre: Introduce una direccion:

Y ahí se detiene para que introduzca la dirección.

Ya he editado el código para abrirlo en binario en vez de en fichero de texto.

Gracias.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: do-while en 10 Febrero 2012, 16:54 pm
Y yo ya te he dicho en el primer post que he escrito que si te salen los dos mensajes seguidos es porque en alguna parte antes de llamar a tu funcion, has dejado informacion en la entrada. Tambien te he dicho que el codigo que te he dado tienes que usarlo despues de scanf, asi como que si pones despues de fgets los gechar no podras leer los datos de forma correcta (o si, pero sera una tombola).

Tambien te he corregido el hecho de que si pones despues del fgets los getchar, estaras leyendo informacion que no estaras guardando, asi que si te saltan los dos mensajes uno detras de otro poco arreglas leyendo caracteres que no guardas en ninguna parte, lo que estas haciendo es perder datos.

¡Saludos!


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 10 Febrero 2012, 17:07 pm
Gracias.

Entonces voy a buscar cuándo dejo información antes de llamar a la función.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 10 Febrero 2012, 22:28 pm
Ya lo he solucionado.

Era poniendo getchar(); debajo de

Código
  1. printf("Elija una opcion\n");
  2.    printf("1. Introducir datos\n");
  3.    printf("2. Visualizar nombres de las fichas existentes\n");
  4.    printf("3. Mostrar todos los datos de una persona\n");
  5.    printf("4. Salir");
  6.    scanf("%d",&opcion);
  7.    getchar();

(Se me olvidó ese scanf).


Título: Re: Problema en agenda con ficheros
Publicado por: do-while en 11 Febrero 2012, 03:39 am
¡Buenas!

Me alegro de que hayas encontrado el scanf. Ahora recuerda siempre que scanf deja siempre al menos un caracter '\n'. Por lo tanto toma como costumbre terminar de leer el input.

¡Saludos!


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 11 Febrero 2012, 21:27 pm
Este es el código que me ha quedado al hacer el programa:

Código
  1. /*  Una agenda que maneje los siguientes datos: nombre, dirección, tlf móvil, email, y día,
  2.     mes y año de nacimiento (estos tres últimos datos deberán ser números enteros
  3.     cortos). Deberá tener capacidad para 100 fichas. Se deberá poder añadir un dato
  4.     nuevo, visualizar los nombres de las fichas existentes, o mostrar todos los datos de una
  5.     persona (se preguntará al usuario cual es el nombre de esa persona que quiere
  6.     visualizar). Al empezar el programa, leerá los datos de un fichero llamado “agenda.dat”
  7.     (si existe). Al terminar, guardará todos los datos en ese fichero. */
  8.  
  9.    #include <stdio.h>
  10.    #include <stdlib.h>
  11.    #include <string.h>
  12.  
  13.    int main()
  14.    {
  15.        struct
  16.        {
  17.          char nombre[10];
  18.          char direccion[15];
  19.          int movil;
  20.          char email[20];
  21.           int dia, mes, ano;
  22.        }datos[100];
  23.        char lineas[500],comprobar[10];
  24.        FILE* fichero;
  25.        int opcion,posicion,tamano,i=0,j,aux;
  26.       int c;
  27.        fichero = fopen("agenda.dat", "r+b");
  28.        if(fichero != NULL)
  29.        {
  30.  
  31.        while(!feof(fichero)) //Leemos los datos que contiene el archivo y los almacenamos en datos[100]
  32.        {
  33.          c=fscanf(fichero,"%s",datos[i].nombre);
  34.          fscanf(fichero,"%s",datos[i].direccion);
  35.          fscanf(fichero,"%d",&datos[i].movil);
  36.          fscanf(fichero,"%s",datos[i].email);
  37.          fscanf(fichero,"%d",&datos[i].dia);
  38.          fscanf(fichero,"%d",&datos[i].mes);
  39.          fscanf(fichero,"%d",&datos[i].ano);
  40.          if(c!=-1)i++; // evita incrementar erroneamente
  41.        }
  42.  
  43.  
  44.       rewind(fichero);
  45.  
  46.        do
  47.        {
  48.        do
  49.        {
  50.        printf("Fichas guardadas: %i\n",i);
  51.        printf("Elija una opcion\n");
  52.        printf("1. Introducir datos\n");
  53.        printf("2. Visualizar nombres de las fichas existentes\n");
  54.        printf("3. Mostrar todos los datos de una persona\n");
  55.        printf("4. Salir\n");
  56.        scanf("%d",&opcion);
  57.        getchar();
  58.  
  59.        switch(opcion)
  60.        {
  61.          case 1:
  62.               printf("Introduce un nombre: ");
  63.               scanf("%s",datos[i].nombre);
  64.  
  65.               printf("Introduce una direccion: ");
  66.  
  67.               scanf("%s",datos[i].direccion);
  68.               printf("Introduce un movil: ");
  69.               scanf("%d",&datos[i].movil);
  70.               while(getchar() != '\n');
  71.               printf("Introduce correo electronico: ");
  72.  
  73.               scanf("%s",datos[i].email);
  74.               printf("Introduce dia de nacimiento: ");
  75.               scanf("%d",&datos[i].dia);
  76.               while(getchar() != '\n');
  77.               printf("Introduce mes de nacimiento: ");
  78.               scanf("%d",&datos[i].mes);
  79.               while(getchar() != '\n');
  80.               printf("Introduce ano de nacimiento: ");
  81.               scanf("%d",&datos[i].ano);
  82.               i++;
  83.               break;
  84.          case 2:
  85.               for(j=0;j<i;j++)
  86.               {
  87.                 printf("%s\n",datos[j].nombre);
  88.               }
  89.  
  90.  
  91.               break;
  92.          case 3:
  93.              printf("Introduce el nombre de la persona de la que desea visualizar los datos:");
  94.             scanf("%s",comprobar);
  95.              for(j=0;j<i;j++)
  96.              {
  97.                if(strcmp(datos[j].nombre,comprobar)==0)
  98.                {
  99.                  printf("Nombre: %s\n",datos[j].nombre);
  100.                  printf("Direccion: %s\n",datos[j].direccion);
  101.                  printf("Movil: %d\n",datos[j].movil);
  102.                  printf("Email: %s\n",datos[j].email);
  103.                  printf("Dia de nacimiento: %d\n",datos[j].dia);
  104.                  printf("Mes de nacimiento: %d\n",datos[j].mes);
  105.                  printf("Ano de nacimiento: %d\n",datos[j].ano);
  106.                }
  107.              }
  108.               break;
  109.          case 4:
  110.               break;
  111.          default:
  112.                  printf("Opcion no valida!\n");
  113.        }
  114.  
  115.        }while(opcion<1||opcion>4);
  116.  
  117.        }while(opcion!=4);
  118.        }
  119.        aux=i;
  120.        for(i=0;i<aux;i++)
  121.        {
  122.          fprintf(fichero, "%s\n", datos[i].nombre);
  123.          fprintf(fichero, "%s\n", datos[i].direccion);
  124.          fprintf(fichero, "%d\n", datos[i].movil);
  125.          fprintf(fichero, "%s\n", datos[i].email);
  126.          fprintf(fichero, "%d\n", datos[i].dia);
  127.          fprintf(fichero, "%d\n", datos[i].mes);
  128.          fprintf(fichero, "%d\n", datos[i].ano);
  129.          }
  130.       fclose(fichero);
  131.  
  132.        printf("\n\nPulse una tecla para continuar");
  133.        getchar();
  134.        return 0;
  135.    }
  136.  

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: s00rk en 11 Febrero 2012, 21:45 pm
Este es el código que me ha quedado al hacer el programa:

Código
  1. /*  Una agenda que maneje los siguientes datos: nombre, dirección, tlf móvil, email, y día,
  2.     mes y año de nacimiento (estos tres últimos datos deberán ser números enteros
  3.     cortos). Deberá tener capacidad para 100 fichas. Se deberá poder añadir un dato
  4.     nuevo, visualizar los nombres de las fichas existentes, o mostrar todos los datos de una
  5.     persona (se preguntará al usuario cual es el nombre de esa persona que quiere
  6.     visualizar). Al empezar el programa, leerá los datos de un fichero llamado “agenda.dat”
  7.     (si existe). Al terminar, guardará todos los datos en ese fichero. */
  8.  
  9.    #include <stdio.h>
  10.    #include <stdlib.h>
  11.    #include <string.h>
  12.  
  13.    int main()
  14.    {
  15.        struct
  16.        {
  17.          char nombre[10];
  18.          char direccion[15];
  19.          int movil;
  20.          char email[20];
  21.           int dia, mes, ano;
  22.        }datos[100];
  23.        char lineas[500],comprobar[10];
  24.        FILE* fichero;
  25.        int opcion,posicion,tamano,i=0,j,aux;
  26.       int c;
  27.        fichero = fopen("agenda.dat", "r+b");
  28.        if(fichero != NULL)
  29.        {
  30.  
  31.        while(!feof(fichero)) //Leemos los datos que contiene el archivo y los almacenamos en datos[100]
  32.        {
  33.          c=fscanf(fichero,"%s",datos[i].nombre);
  34.          fscanf(fichero,"%s",datos[i].direccion);
  35.          fscanf(fichero,"%d",&datos[i].movil);
  36.          fscanf(fichero,"%s",datos[i].email);
  37.          fscanf(fichero,"%d",&datos[i].dia);
  38.          fscanf(fichero,"%d",&datos[i].mes);
  39.          fscanf(fichero,"%d",&datos[i].ano);
  40.          if(c!=-1)i++; // evita incrementar erroneamente
  41.        }
  42.  
  43.  
  44.       rewind(fichero);
  45.  
  46.        do
  47.        {
  48.        do
  49.        {
  50.        printf("Fichas guardadas: %i\n",i);
  51.        printf("Elija una opcion\n");
  52.        printf("1. Introducir datos\n");
  53.        printf("2. Visualizar nombres de las fichas existentes\n");
  54.        printf("3. Mostrar todos los datos de una persona\n");
  55.        printf("4. Salir\n");
  56.        scanf("%d",&opcion);
  57.        getchar();
  58.  
  59.        switch(opcion)
  60.        {
  61.          case 1:
  62.               printf("Introduce un nombre: ");
  63.               scanf("%s",datos[i].nombre);
  64.  
  65.               printf("Introduce una direccion: ");
  66.  
  67.               scanf("%s",datos[i].direccion);
  68.               printf("Introduce un movil: ");
  69.               scanf("%d",&datos[i].movil);
  70.               while(getchar() != '\n');
  71.               printf("Introduce correo electronico: ");
  72.  
  73.               scanf("%s",datos[i].email);
  74.               printf("Introduce dia de nacimiento: ");
  75.               scanf("%d",&datos[i].dia);
  76.               while(getchar() != '\n');
  77.               printf("Introduce mes de nacimiento: ");
  78.               scanf("%d",&datos[i].mes);
  79.               while(getchar() != '\n');
  80.               printf("Introduce ano de nacimiento: ");
  81.               scanf("%d",&datos[i].ano);
  82.               i++;
  83.               break;
  84.          case 2:
  85.               for(j=0;j<i;j++)
  86.               {
  87.                 printf("%s\n",datos[j].nombre);
  88.               }
  89.  
  90.  
  91.               break;
  92.          case 3:
  93.              printf("Introduce el nombre de la persona de la que desea visualizar los datos:");
  94.             scanf("%s",comprobar);
  95.              for(j=0;j<i;j++)
  96.              {
  97.                if(strcmp(datos[j].nombre,comprobar)==0)
  98.                {
  99.                  printf("Nombre: %s\n",datos[j].nombre);
  100.                  printf("Direccion: %s\n",datos[j].direccion);
  101.                  printf("Movil: %d\n",datos[j].movil);
  102.                  printf("Email: %s\n",datos[j].email);
  103.                  printf("Dia de nacimiento: %d\n",datos[j].dia);
  104.                  printf("Mes de nacimiento: %d\n",datos[j].mes);
  105.                  printf("Ano de nacimiento: %d\n",datos[j].ano);
  106.                }
  107.              }
  108.               break;
  109.          case 4:
  110.               break;
  111.          default:
  112.                  printf("Opcion no valida!\n");
  113.        }
  114.  
  115.        }while(opcion<1||opcion>4);
  116.  
  117.        }while(opcion!=4);
  118.        }
  119.        aux=i;
  120.        for(i=0;i<aux;i++)
  121.        {
  122.          fprintf(fichero, "%s\n", datos[i].nombre);
  123.          fprintf(fichero, "%s\n", datos[i].direccion);
  124.          fprintf(fichero, "%d\n", datos[i].movil);
  125.          fprintf(fichero, "%s\n", datos[i].email);
  126.          fprintf(fichero, "%d\n", datos[i].dia);
  127.          fprintf(fichero, "%d\n", datos[i].mes);
  128.          fprintf(fichero, "%d\n", datos[i].ano);
  129.          }
  130.       fclose(fichero);
  131.  
  132.        printf("\n\nPulse una tecla para continuar");
  133.        getchar();
  134.        return 0;
  135.    }
  136.  

Saludos.

o.O
Exelente, solamente lo que yo talvez agregaria es que a la hora de Agregar un nuevo dato, seria comprobar que no haya mas de 100 datos ya dentro, porque si ya hay 100 e intentas agregar uno nuevo pues dara error, creo que seria lo unico que yo le agregaria.


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 11 Febrero 2012, 22:44 pm
¡Muchas gracias! Se me olvidó poner eso. Ya lo he añadido.

Saludos.


Título: Re: Problema en agenda con ficheros
Publicado por: BlackZeroX en 12 Febrero 2012, 01:31 am
Un consejo cuando sean registros estructurados es mejor usar una BDD en este caso te recomiendo que uses SQLite, asi tus consultas son mas rápidas y no te complicas tanto con códigos largos y complejos y en si el desarrollo de tu aplicación sera mas rápido y simple.

http://www.sqlite.org/

Dulces Lunas!¡.


Título: Re: Problema en agenda con ficheros
Publicado por: DickGumshoe en 12 Febrero 2012, 11:48 am
Gracias por la recomendación.

He estado mirando la página que me has pasado y otras que he encontrado por Internet, y parece muy buena la librería. Todavía no he empezado a usar librerías no incluidas en el compilador, pero cuando termine de leer el manual que estoy siguiendo y de hacer los ejercicios que vienen en él, empezaré a usar librerías que no vienen en el compilador (entre ellas esta que me has pasado).

Saludos y gracias.