[ Foro de C ]
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?
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 :'(
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
¿Cual de todas las versiones de la agenda necesitas? ;-)
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).
Hey! Encontré otro manual que está muy bien tambien pero es de un nivel un poco más avanzado :D.
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. ;-)
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);
...
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
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.");
}
Gracias. GRACIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASSS!!!!!!!!!!!!!!!
getchar(); /* Absorbo la tecla "intro" */
:DDDD
No absorbas teclas. Es malo parar tu salud!
:DDDD
>> 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... ;-)
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
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';
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.)