[ Foro de C ]
He aquí los primeros 3 ejercicios del Capítulo6: Manejo de Ficheros.
6.1_ Crea un programa que vaya leyendo las frases que el usuario teclea y las guarde en un fichero
de texto llamado “registroDeUsuario.txt”. Terminará cuando la frase introducida sea "fin" (esa frase
no deberá guardarse en el fichero).
#include <stdio.h>
#include <string.h>
int main()
{
FILE* ptFichero;
char fin[]="fin";
char frase[60];
ptFichero = fopen("registroDeUsuario.txt", "wt");
printf(" PROGRAMA para ESCRIBIR FRASES.\nCuando quiera salir,"
"escriba la palabra fin.\n\n");
do
{
puts("\nEscriba una FRASE:\n(o fin). \n");
gets(frase);
if (strcmp(frase, fin) == 0)
break;
fprintf(ptFichero, "%s\n", frase);
}
while (strcmp(frase, fin) != 0);
fclose(ptFichero);
return 0;
}
6.3.i_ Un programa que pida al usuario que teclee frases, y las almacene en el fichero
“frases.txt”. Acabará cuando el usuario pulse Intro sin teclear nada. Después deberá mostrar
el contenido del fichero.
#include <stdio.h>
#include <string.h>
int main()
{
FILE* ficheroU;
char frase[61];
int i=0;
ficheroU = fopen("frases.txt", "wt");
printf(" PROGRAMA para ESCRIBIR y almacenar FRASES.\n"
"Cuando quiera salir, simplemente pulse \"Intro\".\n\n");
do
{
if (i == 0)
puts("\nEscriba una FRASE:\n(o pulse \"Intro\"). \n");
else
puts("\nEscriba otra FRASE:\n(o pulse \"Intro\"). \n");
gets(frase);
fprintf(ficheroU, "%s\n", frase);
i++;
}
while (strcmp(frase, "") != 0);
printf("He aqui lo que escribio:\n\n");
fclose(ficheroU);
ficheroU = fopen("frases.txt", "rt");
do
{
fgets(frase, 60, ficheroU);
puts(frase);
}
while (!feof(ficheroU));
getchar();
printf("...Hasta luego!");
getchar();
fclose(ficheroU);
return 0;
}
6.3.ii_ Un programa que pregunte un nombre de fichero y muestre en pantalla el contenido de ese
fichero, haciendo una pausa después de cada 25 líneas, para que dé tiempo a leerlo. Cuando el usua-
rio pulse intro, se mostrarán las siguientes 25 líneas, y así hasta que termine el fichero.
#include <stdio.h>
#include <stdlib.h>
int main()
{
FILE *fichero;
char linea[100], nombre[40];
int i=0;
do
{
printf("\nNombre de fichero: ");
gets(nombre);
fichero = fopen(nombre, "rt");
if (fichero == NULL)
{
printf("No existe el fichero\n\n");
i++;
if (i == 5)
exit(1);
}
}
while (fichero == NULL);
while (!feof(fichero))
{
for (i=0; i<25; i++){
fgets(linea, 100, fichero);
if (!feof(fichero))
{
puts(linea);
}
}
getchar();
}
fclose(fichero);
return 0;
}
.....Saludos!
En el 6.3.i haces una cosa peligrosa:
getchar();
printf("...Hasta luego!");
getchar();
fclose(ficheroU);
Por una parte, aunque esto va en gustos, los "getchar" no deberían conservarse en un "programa terminado", porque los necesitas sólo si lanzas tu programa "de consola" desde uno "de ventanas", de modo que se cierra la consola sin darte tiempo a leer. Si lanzas tu programa de consola desde una ventana de consola (que debería ser "lo natural"), esos "getchar" son innecesarios. Lo mismo ocurre si usas un entorno "de ventanas" que sí haga una pausa al terminar la ejecución. Por ejemplo, yo uso Geany, que se comporta así.
Por otra parte, cierra siempre los ficheros tan pronto como sea posible, para evitar una posible pérdida de datos. Si tienes que incluir algún "getchar" o alguna petición de datos al usuario, cierra primero el fichero (esto es especialmente crítico si escribes en fichero, no tan importante si lees de él):
fclose(ficheroU);
printf("...Hasta luego!");
getchar();
getchar();
Gracias, estimado Nacho, por las observaciones.
Mi sistema operativo es Windows XP, el entorno es Dev-C++.
Olvido quitar los getchar(), sin los cuales no puedo ver nada.
Realmente me encuentro paralizado. Estoy tratando de asimilar
un poco más el manejo de ficheros. Parece que he llegado a donde
no es permitido a un simple mortal.
El ejercicio de la agenda me tiene bloqueado.
Por el momento dejo pendiente el ejercicio 6.4.iii, hasta que lo pueda realizar a mi manera.
He aquí los siguientes ejercicios, saltándome por el momento el
de la agenda(6.4.iii):
/*6.4.i_ Crear un struct que almacene los siguientes datos de una persona: nombre, edad, ciudad de
residencia. Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado
“gente.dat”. Cerrar el fichero, volverlo a abrir para lectura y mostrar los datos que se habían
guardado. */
#include <stdio.h>
int main()
{
struct datos
{
char nombre[21];
int edad;
char ciudad[21];
}persona;
FILE *fichero;
int i;
fichero = fopen("gente.dat", "wt");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
puts("Nombre:");
gets(persona.nombre);
fprintf(fichero, "%s ", persona.nombre);
puts("Edad:");
scanf("%d", &persona.edad);
getchar();
fprintf(fichero, "%d ", persona.edad);
puts("Ciudad:");
gets(persona.ciudad);
fputs(persona.ciudad, fichero);
fclose(fichero);
}
fichero = fopen("gente.dat", "rt");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
while (!feof(fichero))
// while (feof(fichero) == 0)
{
fgets(persona.nombre, 60, fichero);
puts(persona.nombre);
fscanf(fichero, "%d", &persona.edad);
getchar();
printf("%d", persona.edad);
fgets(persona.ciudad, 60, fichero);
puts(persona.ciudad);
}
fclose(fichero);
}
return 0;
}
/* 6.4.ii_ Ampliar el programa anterior para que use un “array de structs”, de forma que se puedan
tener datos de 10 personas. Se deberá pedir al usuario los datos de las 10 personas y guardarlos
en el fichero. Después se pedirá al usuario un número del 1 al 10 y se mostrarán los datos de la
persona indicada por ese número, que se deberán leer de fichero (1 será la primera ficha, y 10 será
la última). Por ejemplo, si el usuario indica que quiere ver los datos de la persona 3 (tercera),
se deberá leer las dos primeras, ignorando su contenido, y después leer la tercera, que sí se deberá
mostrar. */
#include <stdio.h>
#include <stdlib.h>
int main()
{
struct datos
{
char nombre[21];
int edad;
char ciudad[21];
}persona[10]; // Array de struct con datos para 10 personas.
FILE *fichero;
int i, numero=0;
fichero = fopen("gente.dat", "wt");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
for (i=0; i<10; i++) //Pide datos de 10 personas y los guarda en el fichero.
{
puts("Nombre:");
gets(persona[i].nombre);
fprintf(fichero, "%s", persona[i].nombre);
puts("Edad:");
scanf("%d", &persona[i].edad);
getchar();
fprintf(fichero, "%d", persona[i].edad);
puts("Ciudad:");
gets(persona[i].ciudad);
fputs(persona[i].ciudad, fichero);
}
}
fclose(fichero);
fichero = fopen("gente.dat", "rt");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
puts("Escriba el numero del fichero a leer:\n" // Pide número del 1 al 10.
"(Para salir, digite 0).");
scanf("%d", &numero);
for (i=0; i<numero; i++) // Muestra los datos de la persona indicada por su número.
{ // Se leen todas las anteriores al número
if (i == (numero-1)) // indicado, pero no se muestran.
{
printf("Nombre:%s\nEdad:%d\nCiudad:%s\n",
persona[i].nombre, persona[i].edad, persona[i].ciudad);
getchar();
}
}
}
while(numero!=0);
fclose(fichero);
}
return 0;
}
/*6.6.i_ Un programa que pida al usuario que teclee frases, y las almacene en el fichero
"registro.txt", que puede existir anteriormente (y que no deberá borrarse, sino añadir al final
de su contenido). Cada sesión acabará cuando el usuario pulse Intro sin teclear nada. */
#include <stdio.h>
#include <string.h>
int main()
{
FILE *fichero;
char frase[61];
int i;
fichero = fopen("registro.txt", "a+");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
fgets(frase, 60, fichero);
puts(frase);
}
while (!feof(fichero));
puts("Escriba algunas frases.\n \"Enter\" para salir.\n");
do
{
puts("Frase: \n");
gets(frase);
fprintf(fichero, "%s\n", frase);
}
while (strcmp(frase, "") != 0);
fclose(fichero);
}
return 0;
}
/* 6.6.ii_ Crear un programa que pida al usuario pares de números enteros y escriba su suma (con el
formato "20 + 3 = 23") en pantalla y en un fichero llamado "sumas.txt", que se encontrará en un
subdirectorio llamado "resultados". Cada vez que se ejecute el programa, deberá añadir los nuevos
resultados a continuación de los resultados de las ejecuciones anteriores. */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
FILE *resultados;
int numero1=0, numero2=0, suma=0;
resultados = fopen("sumas.txt", "a+");
if (resultados == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
fscanf(resultados, "%d + %d = %d", &numero1, &numero2, &suma);
if (feof(resultados))
break;
printf("%d + %d = %d\n", numero1, numero2, suma);
}
while (!feof(resultados));
printf("Escriba dos numeros.\n\"000\" para salir.\n");
do
{
printf("Primer numero: ");
scanf("%d", &numero1);
if (numero1 == 0)
exit(1);
printf("Segundo numero: ");
scanf("%d", &numero2);
suma = numero1 + numero2;
printf("%d + %d = %d\n", numero1, numero2, suma);
fprintf(resultados, "%d + %d = %d\n", numero1, numero2, suma);
}
while (numero1 != 0);
fclose(resultados);
}
return 0;
}
Saludos....!
Pablo, apenas un par de comentarios a tus últimas aportaciones:
- En el 6.6.i, no es necesario que leas los datos existentes en el fichero, basta con que añadas al final.
- En el 6.6.ii, cuidado con el "exit", porque abandonas el programa en un punto inesperado... y no cierras el fichero, lo que puede provocar una pérdida de datos. Por eso es preferible intentar evitar los "exit" y plantear las condiciones de otra forma. En tu caso, podría ser "si el número no es cero, pedir el otro número... etc".
- La parte básica del ejercicio de la agenda se parece al 6.4.ii. ¿Qué dudas tienes?
Gracias nuevamente, estimado Nacho, por las valiosas 0bservaciones.
Es que la agenda me confundió más porque empecé a buscar en el foro
y revolví los conceptos entre las varias versiones que muchos han
aportado. Me está preocupando el uso de fwrite y fread,
pero creo que ya le voy a ir dando forma.
También me tiene confundido el 6.8.i con el 6.8.ii, no encuentro
la diferencia. Supongo que el 6.8.ii debe ser la promoción del an-
terior, pero no encuentro eso en el enunciado.
Este es uno de los mencionados:
/*6.8.i_ Mejorar la agenda anterior(6.4.i), para guardar y leer cada “ficha” (struct) de una vez,
usando fwrite/fread y sizeof, como en el último ejemplo. */
#include <stdio.h>
int main()
{
struct datos
{
char nombre[21];
int edad;
char ciudad[20];
}persona;
FILE *fichero;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
printf("Nombre: ");
scanf("%s", persona.nombre);
printf("Edad: ");
scanf("%d", &persona.edad);
printf("Ciudad: ");
scanf("%s", persona.ciudad);
fwrite(&persona, 1, sizeof(struct datos), fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
fread(&persona, sizeof (struct datos), 1, fichero);
printf("\n%s", persona.nombre);
printf("\n%d", persona.edad);
printf("\n%s", persona.ciudad);
fclose(fichero);
}
return 0;
}
Saludos...!
Siempre solicitándole su valiosa ayuda, estimado nacho. Este es el
ejercicio 6.4c(yo lo tenía como 6.4.iii) el de la agenda que había
dejado pendiente.
Me compila, pero al correr la opción 3, no me muestra los datos de
la última persona. Al correrlo varias veces se llena de ceros y otras locuras. Entiendo que en parte es por la falta de detalles como los que Ud. le pone: Por ejemplo, borrar el \n del final de la línea. Esa parte no la entiendo.
Si es tan amable, me puede decir qué es lo más grave de este código. O sea, cómo quedaría lo más sencillo posible sin muchas complicaciones, pero que funcione.
6.4c_ 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.
#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 diaNac, mesNac, anyoNac;
}persona[100];
FILE* fichero;
char textoTemporal[21];
int opcion, personas=-1;
int i;
fichero = fopen("agenda.dat", "rt");
if (fichero != NULL)
{
while (! feof(fichero))
{
fscanf(fichero, "%s", persona[i].nombre);
if (feof(fichero)) break;
printf("%s\n", persona[i].nombre);
fscanf(fichero, "%s", persona[i].direccion);
if (feof(fichero)) break;
printf("%s\n", persona[i].direccion);
fscanf(fichero, "%s", persona[i].celular);
if (feof(fichero)) break;
printf("%s\n", persona[i].celular);
fscanf(fichero, "%s", persona[i].email);
if (feof(fichero)) break;
printf("%s\n", persona[i].email);
fscanf(fichero, "%hd%hd%hd", &persona[i].diaNac, &persona[i].mesNac, &persona[i].anyoNac);
if (feof(fichero)) break;
printf("%hd %hd %hd\n\n", persona[i].diaNac, persona[i].mesNac, persona[i].anyoNac);
personas++;
}
fclose(fichero);
}
printf("Leidos %d datos", personas+1);
do
{
puts("\n\n MENU:\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 */
printf ("Introduce nombre: ");
gets (persona[personas+1].nombre);
fprintf(fichero, "%s", persona[personas+1].nombre);
printf ("Introduce direccion: ");
gets (persona[personas+1].direccion);
fprintf(fichero, "%s", persona[personas+1].direccion);
printf ("Introduce celular: ");
gets (persona[personas+1].celular);
fprintf(fichero, "%s", persona[personas+1].celular);
printf ("Introduce correo electronico: ");
gets (persona[personas+1].email);
fprintf(fichero, "%s", persona[personas+1].email);
printf ("Introduce dia de nacimiento: ");
scanf("%hd", &persona[personas+1].diaNac);
fprintf(fichero, "%hd", persona[personas+1].diaNac);
printf ("Introduce mes de nacimiento: ");
scanf ("%hd", &persona[personas+1].mesNac);
fprintf(fichero, "%hd", persona[personas+1].mesNac);
printf ("Introduce año de nacimiento: ");
scanf ("%hd", &persona[personas+1].anyoNac);
fprintf(fichero, "%hd", persona[personas+1].anyoNac);
personas ++;
break;
case 2: /* Ver todos los nombres */
puts ("Ver todos los nombres existentes:");
for (i=0; i<=personas; i++)
puts (persona[i].nombre);
break;
case 3: /* Ver todos los datos de una persona */
printf ("Nombre a buscar? ");
for (i=0; i<=personas; i++)
{
gets(textoTemporal);
if (strcmp (textoTemporal, persona[i].nombre) != 0) break;
{
puts (persona[i].nombre);
puts (persona[i].direccion);
puts (persona[i].celular);
puts (persona[i].email);
printf("%hd %hd %hd.\n", persona[i].diaNac,
persona[i].mesNac, persona[i].anyoNac);
}
}
break;
}
}
while (opcion != 0);
fichero = fopen("agenda.dat", "wt");
for (i=0; i<=personas; i++)
{
fprintf (fichero, "%s\n", persona[i].nombre);
fprintf (fichero, "%s\n", persona[i].direccion);
fprintf (fichero, "%s\n", persona[i].celular);
fprintf (fichero, "%s\n", persona[i].email);
fprintf (fichero, "%hd %hd %hd\n",
persona[i].diaNac, persona[i].mesNac, persona[i].anyoNac);
}
fclose(fichero);
return 0;
}
Agradezco su ayuda. Saludos.
Así entendí el ejercicio 6.8b:
6.8b_ Crear un “struct” que almacene los siguientes datos de una persona: nombre, edad, ciudad
de residencia. Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado
“gente.dat”, usando “fwrite”. Cerrar el fichero, volverlo a abrir para lectura y mostrar los datos
que se habían guardado, que se deben leer con “fread”.
#include <stdio.h>
struct datos
{
char nombre[21];
int edad;
char ciudad[20];
}persona[10]; /* Para mejorar el ejercicio anterior,
agregué arreglo de 10 structs. */
int main()
{
FILE *fichero;
int i=0;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
printf("Nombre: ");
fflush(stdout);
gets(persona[i].nombre);
printf("Edad: ");
fflush(stdout);
scanf("%d", &persona[i].edad);
printf("Ciudad: ");
fflush(stdout);
scanf("%s", persona[i].ciudad);
fflush(stdin);
i++;
}
while (i < 10);
fwrite(&persona[i], sizeof(persona), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
fread(&persona[i], sizeof (persona), 1, fichero);
for (i=0; i<10; i++)
{
printf("\n%s ", persona[i].nombre);
printf("%d ", persona[i].edad);
printf("%s\n", persona[i].ciudad);
}
fclose(fichero);
}
}
Saludos.....!
Estimado Nacho, en este ejercicio tengo problemas con fread.
6.8c_ Ampliar el programa anterior para que use un “array de structs”, de forma que se puedan
tener datos de 10 personas. Se deberá pedir al usuario los datos de las 10 personas y guardarlos
en el fichero, usando “fwrite”. Después se pedirá al usuario un número del 1 al 10 y se mostra-
rán los datos de la persona indicada por ese número, que se deberán leer de fichero (1 será la
primera ficha, y 10 será la última). Por ejemplo, si el usuario indica que quiere ver los datos
de la persona 3 (tercera), se deberá leer las dos primeras (con “fread”), ignorando su contenido,
y después leer la tercera, que sí se deberá mostrar.
#include <stdio.h>
struct datos
{
char nombre[21];
int edad;
char ciudad[20];
}persona[10];
int main()
{
FILE *fichero;
int i=0, numero;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
printf("Nombre: ");
fflush(stdout);
gets(persona[i].nombre);
printf("Edad: ");
fflush(stdout);
scanf("%d", &persona[i].edad);
printf("Ciudad: ");
fflush(stdout);
scanf("%s", persona[i].ciudad);
fflush(stdin);
i++;
}
while (i < 10);
fwrite(&persona[i], sizeof(persona), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
/* AQUÍ no sé cómo usar FREAD. ¡Ayuda, por favor! */
/* while (fread(&persona[i], sizeof(persona), 1, fichero) == 1)
printf("Nombre:%s\nEdad:%d\nCiudad:%s\n",
persona[i].nombre, persona[i].edad, persona[i].ciudad); */
do
{
puts("Escriba el numero del fichero a leer:\n"
"(Para salir, escriba 0).");
scanf("%d", &numero);
for (i=0; i<numero; i++)
{
if (i == (numero-1))
{
printf("Nombre:%s\nEdad:%d\nCiudad:%s\n",
persona[i].nombre, persona[i].edad, persona[i].ciudad);
getchar();
}
}
}
while ((numero > 0) && (numero <= 10));
fclose(fichero);
}
}
.....Saludos!
S... O... S..!!!
Si alguien me puede ayudar, le agradeceré por el resto de mi vida, jejeje!
Creía que ya los manejaba, pero acabo de darme cuenta que no puedo usar la tripleta
FWRITE/FREAD/SIZEOF, ni en el más sencillo de los ejercicios.
El profesor Nacho da un buen ejemplo del uso de estas funciones cuando copia un archivo en
otro; pero, no logro adaptarlo a este ejercicio que aparentemente es más sencillo. Lo básico:
escribir en, y leer de un archivo.
Probando con el siguiente código, eliminé (comenté) las dos líneas que incluyen a fread/fwrite
y sizeof, y el resultado fué el mismo. O sea que, no estoy ni guardando en archivo ni leyendo
del archivo. Simplemente estoy recuperando de la manera más vulgar lo que guardé en el struct.
Si alguien me puede decir qué hay de malo con el código siguiente, qué es lo que le falta, y,
cómo se lograría de la manera más sencilla posible:
6.8.i_ Mejorar la agenda anterior(6.4.i), para guardar y leer cada “ficha” (struct) de una vez,
usando fwrite/fread y sizeof, como en el último ejemplo.
#include <stdio.h>
int main()
{
struct datos
{
char nombre[21];
int edad;
char ciudad[21];
}persona; /* El ejercicio pide un array, pero aún para una sola ficha no me funciona. */
FILE *fichero;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
printf("Nombre: ");
scanf("%s", persona.nombre);
printf("Edad: ");
scanf("%d", &persona.edad);
printf("Ciudad: ");
scanf("%s", persona.ciudad);
/* Da lo mismo, si quito la siguiente línea. */
fwrite(&persona, sizeof(struct datos), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
/* Igual, si elimino esta otra, o ambas. */
fread(&persona, sizeof (struct datos), 1, fichero);
printf("\n%s", persona.nombre);
printf("\n%d", persona.edad);
printf("\n%s", persona.ciudad);
fclose(fichero);
}
return 0;
}
Creo que si entiendo este sencillo ejercicio voy a poder encarar los que siguen, pues éste
es como el prerequisito.
.....Gracias de antemano!
Mientras no viene Nacho te comento algo para que vayas intentándolo tu:
En primer lugar, creo que esta parte no es correcta (sobra lo de "datos")
struct datos
{
char nombre[21];
int edad;
char ciudad[21];
}persona;
Creo que debiera ser:
struct {
char nombre[21];
int edad;
char ciudad[21];
}persona;
Por lo tanto, cuando pones lo de sizeof(struct datos) debiera ser sizeof(persona), y con eso creo que el programa ya te funciona.
Un saludo!
Hay alguna otra cosa que debieras corregir, como por ejemplo cambiar los "scanf" cuando recibes cadenas de texto por "gets"
gets(persona.nombre);
para evitar problemas con los espacios (y me parece que codigo queda más limpio xD)
Además debieras añadir un getchar() despues del scanf que recibe la edad, para evitar problemas con el "enter" que pulsa el usuario después de introducir la edad
printf("Edad: ");
scanf("%d", &persona.edad);
getchar();
Un saludo!
Veamos Pablo...
En el ejercicio, 6.4.3, de la agenda: en general está bastante bien, pero tiene algún fallo. Por ejemplo:
- No inicializas la variable "i", de modo que el "fscanf(fichero, "%s", persona[i].nombre);" puede estar accediendo a cualquier sitio, no necesariamente a la ficha inicial, y quizá incluso fuera del rango de los datos. Si miras mi propuesta de solución, verás que guardo usando el contador de fichas (ultimaFicha+1). En tu caso sería: fscanf(fichero, "%s", persona[personas+1].nombre);
- Cuando lees la fecha de nacimiento (día, mes, año), no los separas por ningún espacio ni ningún carácter distintivo, de moo que algo como 12101980 parecería un "único número grande". Compara tu "fscanf(fichero, "%hd%hd%hd"," con mi "%hd %hd %hd"
- En general, se parece mucho al mío, así que supongo que te habrás basado en él, en vez de hacerlo desde cero. Si lo que tienes son dudas con el esqueleto básico del programa, mira la propuesta para el ejercicio 5.5.2b:
http://www.nachocabanes.com/c/curso/c_soluciones.php#050502b
Puedes añadir soporte de ficheros a ese ejemplo, para practicar. En un primer acercamiento, podrías leer todo al principio de la ejecución y guardar todo al salir, como en el 6.4c.
Gracias Antonio por tu deferencia.
Ya hice lo que me recomiendas y lo mismo.
El programa funciona, pero no están operando las funciones de
guardar en archivo (fwrite), leer de archivo (fread), ni tam-
poco sizeof. Lo sé por estas dos razones que he comprobado:
1.- Elimino la línea que contiene fwrite, o la que contiene a
fread, o ambas, y funciona igual que con ellas.
2.-Si abro el archivo en el modo "ab", me sigue presentando los
datos que tenía cuando lo abrí la última vez en el modo "wb"
y no me presenta los datos que estoy introduciendo actualmente.
De lo anterior deduzco que no estoy guardando en archivo, ni estoy leyendo del archivo; sino más bien, sólo estoy recuperando lo que se guardó en el struct.
Mi preocupación es que no puedo usar FWRITE/FREAD/SIZEOF.
Este ejercicio me gusta para poderlo entender bien, porque es de los más sencillos.
Reitero: el código parece que funciona (así lo creí al principio),
pero no es así.
Si tienes algotra sugerencia, te lo agradeceré; de lo contrario,
esperaré a ver qué dice el Profesor (sé que a él ésto le va a parecer "muerto de la risa", pero para mí es por el momento un
completo valladar).
Saludos, Antonio.
Gracias, estimado Nacho por su respuesta.
Antes que nada quiero disculparme por tergiversar los números de los ejercicios. Por ejemplo, a éste lo nominé como 6.4.iii, después
me dí cuenta que es el 6.4c. En adelante utilizaré esta nomencla-
tura.
A propósito de este ejercicio (la agenda), expresé que me tenía confundido y realmente quiero dejar muy claro ante el honorable foro que no me basé en su fuente para realizarlo; jamás haría algo tan vil. Más bien fue una copia textual, pero mal hecha, jejeje.
Prometo que al ordenar un poco las ideas lo tengo que realizar por
mi cuenta.
Estimado Profesor: por elmomento lo que más me preocupa es el uso
de FWRITE/FREAD/SIZEOF que me parece que son funciones básicas en el trabajo con ficheros de acceso aleatorio o de tipo binario.
Específicamente es el ejercicio 6.8a que trata de un array de 10
structs; y que para simplificarlo aún más, lo realizo con una simple variable de tipo struct (persona). Y ni así lo puedo hacer funcionar. De hecho funciona aparentemente; pero no estoy escribiendo ni leyendo del fichero.
Mi preocupación es por el hecho de ser un ejercicio sencillo, muy
bonito para poder entender el uso de esas funciones básicas; y no
lo he podido concretar.
...Si su paciencia da todavía para más, estaré muy agradecido por su valiosa atención.
Saludo cordial.
Perdón Profesor, es el ejercicio que está como a seis correos
de distancia de aquí hacia atrás. Es el 6.8a, pero que lo nombré
como 6.8i. Es el que inicié con un S...O...S..!
Gracias de nuevo.
Hola Pablo.
Debo decirte que a mí el código sí me funciona, he hecho unas modificaciones para comprobarlo, lo pego aquí y te comento un par de detalles:
#include <stdio.h>
int main()
{
struct {
char nombre[21];
int edad;
char ciudad[21];
}persona;
FILE *fichero;
if ((fichero = fopen("gente8.dat", "ab")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
printf("Nombre: ");
gets(persona.nombre);
printf("Edad: ");
scanf("%d", &persona.edad);
getchar();
printf("Ciudad: ");
gets(persona.ciudad);
fwrite(&persona, sizeof(persona), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente8.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
while (! feof(fichero)) {
fread(&persona, sizeof(persona), 1, fichero);
printf("\n%s", persona.nombre);
printf("\n%d", persona.edad);
printf("\n%s", persona.ciudad);
}
fclose(fichero);
}
return 0;
}
En primer lugar, la línea en la que abrimos el fichero:
if ((fichero = fopen("gente8.dat", "ab")) == NULL)
Como ves, he llamado el fichero de otra forma (gente8.dat) pero lo he hecho solamente para que no me sobreescriba en mis propios ficheros :D Otra cosa que he cambiado es el modo de apertura ("ab") para que al ejecutar el programa añada los datos que introducimos al final del fichero y no cree un fichero nuevo cada vez que se ejecute (que es lo que hacía con "wd") Esto también nos vale para verificar que fwrite funciona, ya que si tras ejecutar el programa un par de veces abrimos el archivo gente8.dat (con el block de notas, por ejemplo) los datos serán ilegibles en su mayoría, pero veremos que van aumentando a medida que ejecutamos el programa, con lo que efectivamente está escribiendo.
En la parte de lectura del fichero he hecho otra modificación:
while (! feof(fichero)) {
fread(&persona, sizeof(persona), 1, fichero);
printf("\n%s", persona.nombre);
printf("\n%d", persona.edad);
printf("\n%s", persona.ciudad);
}
Simplemente he añadido "while (! feof(fichero))" para que la lectura se haga de todos los datos del fichero, así verás que no solamente lee los datos de la ultima ficha introducida, si no que está leyendo los datos que has introducido en otras ejecuciones del programa (y que han sido guardados en el fichero gracias a que estamos escribiendo con "ab").
Espero que estas indicaciones sirvan para orientarte, y no para confundirte todavía más :)
Un saludo!
Vamos por partes...
El enunciado del 6.8a dice
Apartado 6.8a: Mejorar la agenda anterior, para guardar y leer cada “ficha” (struct) de una vez, usando fwrite/fread y sizeof, como en el último ejemplo.
No dice que se base en el 6.4a, que no es la agenda sino una primera toma de contacto. Está pensado para que te bases en el 6.4c, pero claro, para eso primero tienes que haber asimilado correctamente el 6.4c. Por eso decía que era interesante analizar y entender primero el 5.5.2b.
Si quieres convertir el 6.4a para que use fread y fwrite, me parece un ejercicio razonable como primer acercamiento, pero no es lo que se pide en el 6.8a. En ese caso, retrocedo a tu propuesta para el 6.4a, miro la del 6.8a y comparo, para ver los fallos, aunque eso que hablas del modo "ab" ya me hace sospechar, porque el modo "a" (añadir, append) está pensado para ficheros de texto. Pero es que, en cualquier caso, el 6.4a estaba pensado para guardar una única ficha, no varias...
Veamos... tu propuesta para el 6.4a es:
#include <stdio.h>
int main()
{
struct datos
{
char nombre[21];
int edad;
char ciudad[21];
} persona;
FILE *fichero;
int i;
fichero = fopen("gente.dat", "wt");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
puts("Nombre:");
gets(persona.nombre);
fprintf(fichero, "%s ", persona.nombre);
puts("Edad:");
scanf("%d", &persona.edad);
getchar();
fprintf(fichero, "%d ", persona.edad);
puts("Ciudad:");
gets(persona.ciudad);
fputs(persona.ciudad, fichero);
fclose(fichero);
}
fichero = fopen("gente.dat", "rt");
if (fichero == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
while (!feof(fichero))
// while (feof(fichero) == 0)
{
fgets(persona.nombre, 60, fichero);
puts(persona.nombre);
fscanf(fichero, "%d", &persona.edad);
getchar();
printf("%d", persona.edad);
fgets(persona.ciudad, 60, fichero);
puts(persona.ciudad);
}
fclose(fichero);
}
return 0;
}
Correcciones necesarias:
- Dado que "fgets" lee una línea, lo razonable es que cuando escribas los datos, los termines con \n, no con un espacio en blanco.
- El "getchar" que hay por ahí no sirve de nada: lee de consola y tú estás accediendo a fichero.
- El "fclose" debería ir dentro del "else": no puedes cerrar un fichero que no has conseguido abrir.
Vamos ahora con tu propuesta para la variante que usa "fwrite":
#include <stdio.h>
int main()
{
struct datos
{
char nombre[21];
int edad;
char ciudad[21];
}persona; /* El ejercicio pide un array, pero aún para una sola ficha no me funciona. */
FILE *fichero;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
printf("Nombre: ");
scanf("%s", persona.nombre);
printf("Edad: ");
scanf("%d", &persona.edad);
printf("Ciudad: ");
scanf("%s", persona.ciudad);
/* Da lo mismo, si quito la siguiente línea. */
fwrite(&persona, sizeof(struct datos), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
/* Igual, si elimino esta otra, o ambas. */
fread(&persona, sizeof (struct datos), 1, fichero);
printf("\n%s", persona.nombre);
printf("\n%d", persona.edad);
printf("\n%s", persona.ciudad);
fclose(fichero);
}
return 0;
}
Comentarios sobre éste:
- La estructura es buena, salvo por pequeños detalles, como que yo usaría "gets" en vez de "scanf" para las cadenas, para permitir espacios en blanco intermedios (ya sabes que eso puede obligar a que añadas algún "getchar").
- Dará igual si eliminas las dos líneas, efectivamente, porque los datos están en memoria. Si no guardas en fichero y no lees, se siguen mostrando los valores que había en la memoria. Aunque sí existirá una diferencia: el fichero estará vacío. Para comprobar que sí está funcionando, puedes "borrar" los valores entre la lectura y la escritura, haciendo
strcpy(persona.nombre, "");
persona.edad = 0;
strcpy(persona.ciudad, "");
Si después de eso, lees y consigues mostrar los valores correctos, estará claro que está funcionando.
Me siento honrado y altamente agradecido por las esclarecedoras respuestas brindadas por Antonio y el Profesor Nacho.
Voy a dedicar un buen rato a asimilar tan valiosos aportes y a
ordenar ideas y volver a realizar algunos ejercicios que había mal interpretado, ya sea conceptual o mecanograficamente.
Nuevamente gracias y me voy a recluir por un buen rato. Luego saldré a la luz con más fuentes resueltos, espero; y alguna que
otra consulta.
.....Saludos cordiales.
He aquí otros ejercicios resueltos:
(Aclaro que la primera versión de la agenda es una copia mutilada
de la que muestra el Profesor Nacho). :-I
/*6.4c_ Una agenda (AGENDA versión 0.01) 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. */
#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 opcion, personas=0;
int i, j;
fichero = fopen("agenda.dat", "rt");
if (fichero != NULL)
{
while (! feof(fichero))
{
fgets(textoAux, 20, fichero);
if (feof(fichero)) break;
if (strlen(textoAux) > 0)
textoAux[strlen(textoAux) -1] = '\0';
strcpy(persona[personas].nombre, textoAux);
puts(persona[personas].nombre);
fgets(textoAux, 20, fichero);
if (feof(fichero)) break;
if (strlen(textoAux) > 0)
textoAux[strlen(textoAux) -1] = '\0';
strcpy(persona[personas].direccion, textoAux);
puts(persona[personas].direccion);
fgets(textoAux, 20, fichero);
if (feof(fichero)) break;
if (strlen(textoAux) > 0)
textoAux[strlen(textoAux) -1] = '\0';
strcpy(persona[personas].celular, textoAux);
puts(persona[personas].celular);
fgets(textoAux, 20, fichero);
if (feof(fichero)) break;
if (strlen(textoAux) > 0)
textoAux[strlen(textoAux) -1] = '\0';
strcpy(persona[personas].email, textoAux);
puts(persona[personas].email);
fgets(textoAux, 20, fichero);
if (feof(fichero)) break;
sscanf(textoAux, "%hd %hd %hd", &persona[personas].dia,
&persona[personas].mes,
&persona[personas].anyo);
if ((persona[personas].dia == 0) || (persona[personas].mes == 0) ||
(persona[personas].anyo == 0))
break;
puts(textoAux);
personas++;
}
fclose(fichero);
}
if (personas == 0) printf("No hay ninguna ficha guardada.");
else
if (personas == 1) printf("He ahi la unica ficha guardada.");
else
printf("He ahi las %d fichas guardadas.", personas);
do
{
puts("\n\n MENU:\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 */
printf ("nombre: ");
gets (persona[personas].nombre);
fprintf(fichero, "%s", persona[personas+1].nombre);
printf ("Direccion: ");
gets (persona[personas].direccion);
fprintf(fichero, "%s", persona[personas+1].direccion);
printf ("Celular: ");
gets (persona[personas].celular);
fprintf(fichero, "%s", persona[personas+1].celular);
printf ("Correo electronico: ");
gets (persona[personas].email);
fprintf(fichero, "%s", persona[personas+1].email);
printf ("Dia de nacimiento: ");
scanf("%hd", &persona[personas].dia);
fprintf(fichero, "%hd", persona[personas+1].dia);
printf ("Mes de nacimiento: ");
scanf ("%hd", &persona[personas].mes);
fprintf(fichero, "%hd", persona[personas+1].mes);
printf ("Año de nacimiento: ");
scanf ("%hd", &persona[personas].anyo);
fprintf(fichero, "%hd", persona[personas].anyo);
personas ++;
break;
case 2: /* Ver todos los nombres */
j = 0;
puts ("Ver todos los nombres existentes:");
for (i=0; i<=personas; i++)
{
puts (persona[i].nombre);
j ++;
}
if (j == 0)
printf("No hay ningun nombre guardado.");
break;
case 3: /* Ver todos los datos de una persona */
puts("Nombre a buscar:");
gets(textoAux);
j = 0;
for (i=0; i<=personas; i++)
{
if (strcmp (textoAux, persona[i].nombre) == 0)
{
puts (persona[i].nombre);
if (strcmp(persona[i].nombre, "") == 0)
break;
puts (persona[i].direccion);
puts (persona[i].celular);
puts (persona[i].email);
printf("%hd %hd %hd.\n", persona[i].dia,
persona[i].mes, persona[i].anyo);
j ++;
}
}
if (j == 0)
printf("No existe esa ficha.");
break;
}
}
while (opcion != 0);
fichero = fopen("agenda.dat", "wt");
for (i=0; i<=personas; i++)
{
fprintf (fichero, "%s\n", persona[i].nombre);
fprintf (fichero, "%s\n", persona[i].direccion);
fprintf (fichero, "%s\n", persona[i].celular);
fprintf (fichero, "%s\n", persona[i].email);
fprintf (fichero, "%hd %hd %hd\n",
persona[i].dia, persona[i].mes, persona[i].anyo);
}
fclose(fichero);
return 0;
}
/*6.8a_ Mejorar la agenda anterior(6.4c), para guardar y leer cada “ficha” (struct) de una vez,
usando fwrite/fread y sizeof, como en el último ejemplo. */
#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 opcion, personas=0;
int i, j;
fichero = fopen("agenda.dat", "rb");
if (fichero != NULL)
{
while (! feof(fichero))
{
fread(&persona[i],sizeof(persona), 1, fichero);
if (feof(fichero)) break;
printf("%s\n", persona[i].nombre);
if (feof(fichero)) break;
printf("%s\n", persona[i].direccion);
if (feof(fichero)) break;
printf("%s\n", persona[i].celular);
if (feof(fichero)) break;
printf("%s\n", persona[i].email);
if (feof(fichero)) break;
printf("%hd %hd %hd\n\n", persona[i].dia, persona[i].mes, persona[i].anyo);
if (feof(fichero)) break;
personas++;
}
fclose(fichero);
}
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 */
printf ("Nombre: ");
gets (persona[personas].nombre);
printf ("Direccion: ");
gets (persona[personas].direccion);
printf ("Celular: ");
gets (persona[personas].celular);
printf ("Correo electronico: ");
gets (persona[personas].email);
printf ("Dia de nacimiento: ");
scanf("%hd", &persona[personas].dia);
printf ("Mes de nacimiento: ");
scanf ("%hd", &persona[personas].mes);
printf ("Año de nacimiento: ");
scanf ("%hd", &persona[personas].anyo);
personas ++;
fwrite(&persona[i], sizeof(persona), 1, fichero);
break;
case 2: /* Ver todos los nombres */
puts ("Ver todos los nombres existentes:");
for (i=0; i<personas; i++)
puts (persona[i].nombre);
break;
case 3: /* Ver todos los datos de una persona */
printf ("Nombre a buscar? ");
gets(textoAux);
j = 0;
for (i=0; i<=personas; i++)
{
if (strcmp (textoAux, persona[i].nombre) == 0)
{
puts (persona[i].nombre);
if (strcmp(persona[i].nombre, "") == 0)
break;
puts (persona[i].direccion);
puts (persona[i].celular);
puts (persona[i].email);
printf("%hd %hd %hd.\n", persona[i].dia,
persona[i].mes, persona[i].anyo);
j ++;
}
}
if (j == 0)
printf("No existe esa ficha.");
break;
}
}
while (opcion != 0);
fichero = fopen("agenda.dat", "wb");
for (i=0; i<personas; i++)
fwrite(&persona[i], sizeof(persona), 1, fichero);
fclose(fichero);
return 0;
}
/* 6.8b_ Crear un “struct” que almacene los siguientes datos de una persona: nombre, edad, ciudad
de residencia. Pedir al usuario esos datos de una persona y guardarlos en un fichero llamado
“gente.dat”, usando “fwrite”. Cerrar el fichero, volverlo a abrir para lectura y mostrar los datos
que se habían guardado, que se deben leer con “fread”. */
#include <stdio.h>
struct datos
{
char nombre[21];
int edad;
char ciudad[20];
}persona;
int main()
{
FILE *fichero;
int i;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
printf("Nombre: ");
gets(persona.nombre);
printf("Edad: ");
scanf("%d", &persona.edad);
/* Después de este primer scanf() no se necesita un getchar(). */
printf("Ciudad: ");
scanf("%s", persona.ciudad);
getchar(); /* Aquí sí, es necesario. */
i++;
}
while (i < 10);
fwrite(&persona, sizeof(persona), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
fread(&persona, sizeof (persona), 1, fichero);
puts(persona.nombre);
printf("%d\n", persona.edad);
puts(persona.ciudad);
fclose(fichero);
}
getchar();
}
/*6.8c_ Ampliar el programa anterior para que use un “array de structs”, de forma que se puedan
tener datos de 10 personas. Se deberá pedir al usuario los datos de las 10 personas y guardarlos
en el fichero, usando “fwrite”. Después se pedirá al usuario un número del 1 al 10 y se mostra-
rán los datos de la persona indicada por ese número, que se deberán leer de fichero (1 será la
primera ficha, y 10 será la última). Por ejemplo, si el usuario indica que quiere ver los datos
de la persona 3 (tercera), se deberá leer las dos primeras (con “fread”), ignorando su contenido,
y después leer la tercera, que sí se deberá mostrar. */
#include <stdio.h>
#include <string.h>
struct datos
{
char nombre[21];
int edad;
char ciudad[20];
}persona[10];
int main()
{
FILE *fichero;
int i=0, numero;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
printf("Nombre: ");
gets(persona[i].nombre);
printf("Edad: ");
scanf("%d", &persona[i].edad);
printf("Ciudad: ");
scanf("%s", persona[i].ciudad);
fflush(stdin); /* Un getchar() bastaría. */
i++;
}
while (i < 10);
fwrite(&persona[i], sizeof(persona), 1, fichero);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
puts("Escriba el numero del fichero a leer:\n"
"(Para salir, escriba 0).");
scanf("%d", &numero);
for (i=0; i<numero; i++)
{
if (i == (numero-1))
{
printf("Nombre:%s\nEdad:%d\nCiudad:%s\n",
persona[i].nombre, persona[i].edad, persona[i].ciudad);
getchar();
}
}
}
while ((numero > 0) && (numero <= 10));
fclose(fichero);
}
getchar();
}
/* 6.9_ Ampliar el programa anterior (el “array de structs” con 10 personas) para que el dato que
indique el usuario se lea sin leer y descartar antes los que le preceden, sino que se salte
directamente a la ficha deseada usando “fseek”. */
#include <stdio.h>
struct datos
{
char nombre[21];
unsigned short int edad;
char ciudad[21];
}persona[10];
int main()
{
FILE *fichero;
int i=0;
unsigned short int numero;
if ((fichero = fopen("gente.dat", "wb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
puts("Nombre:");
gets(persona[i].nombre);
puts("Edad:");
scanf("%hd", &persona[i].edad);
fflush(stdin);
puts("Ciudad:");
gets(persona[i].ciudad);
fwrite(&persona[i], sizeof(persona), 1, fichero);
i++;
}
while (i < 10);
fclose(fichero);
}
if((fichero = fopen("gente.dat", "rb")) == NULL)
printf("No se pudo abrir el archivo.\n");
else
{
do
{
puts("Escriba el numero del fichero a leer:\n"
"(Para salir, escriba 0).");
scanf("%d", &numero);
i = numero-1;
fseek(fichero, 0, SEEK_END);
fread(&persona[i], sizeof(persona), 1, fichero);
printf("Nombre:%s\n Edad:%hd\n Ciudad:%s\n\n",
persona[i].nombre, persona[i].edad, persona[i].ciudad);
}
while ((numero > 0) && (numero <= 10));
fclose(fichero);
}
}
.......Saludos a todos!
Perdón, en el ejercicio próximo anterior (6.9) no estoy usando
correctamente la función fseek; Es más, no está haciendo nada en
el programa. La corrección es la siguiente:
fseek(fichero, sizeof(persona)*(numero-1), SEEK_SET);
fread(&persona[i], sizeof(persona), 1, fichero);
printf("Nombre:%s\n Edad:%hd\n Ciudad:%s\n\n",
persona[i].nombre, persona[i].edad, persona[i].ciudad);
.....Saludos cordiales a todos.
(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.)