[ Foro de C ]

Lectura fichero

03-Jul-2012 14:48
Rudi Merlos Carrion
5 Respuestas

Hola, al probar el ejemplo nº57 (6.3 Lectura hasta el final del fichero) me ocurre que lee todas las lineas del fichero más 1, la última linea la repite. Como lo puedo solucionar?

Gracias


04-Jul-2012 04:01
Pablo Rampa

  Hola, Rudi!

Si pusieras el código, talvez te podría ayudar.
Me parece que tiene que ver con la comprobación del final del    
archivo(EOF). Hay que comprobar el EOF y salir del lazo antes de
que imprima la última línea.

Saludos!


04-Jul-2012 10:24
Rudi Merlos Carrion

Hola!!

Este es el código del ejemplo de Nacho:

#include <stdio.h>

main()
{
   FILE* fichero;
   char nombre[80] = "c:\\autoexec.bat";
   char linea[81];

   fichero = fopen(nombre, "rt");

   if (fichero == NULL)
   {
     printf("No existe el fichero!\n");
     exit(1); //hay que incluir lib <stdlib.h>
   }
   while (! feof(fichero)) {
     fgets(linea, 80, fichero);
     puts(linea);
   }
   fclose(fichero);
}

Aquí, el problema es que lee el fichero hasta el final pero la última linea la repite.

Ahora el ejercicio que yo he hecho (6.3.i):

//Escribir y leer fichero
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main(){
   FILE* fichero;
   char frase[80], line[81];
   
   fichero = fopen("frases.txt", "wt");

   printf("Escribe un texto\n");
   printf("y para finalizar pulsa \"ENTER\":\n\n");
   
   while (strcmp(frase, "") != 0){
       gets(frase);
       if (strcmp(frase, "") == 0)
           break;
       fprintf(fichero, "%s\n", frase);
   }
   
   fclose(fichero);
   
   fichero = fopen("frases.txt", "rt");
   
   if (fichero == NULL){
       printf("No existe el fichero\n");
       exit(1);
   }
   while (!feof(fichero)){
       fgets(frase, 80, fichero);
       if (!feof(fichero))
           fputs(frase, stdout);//gracias a esto no reptite
   }                            //la última linea pero no se
   fclose(fichero);             //porque
   
   return 0;
}

Esto lo aprendí investigando por google pero no se porque funciona. Hay dos cosas que no entiendo:
1 - ¿Que es lo que hace " fputs(frase,stdout); "?
2 - ¿Porque no es necesario imprimir la linea en el programa con " puts(frase); "? Ya que si lo hago me repite todas las lineas.

Gracias


04-Jul-2012 20:14
Rudi Merlos Carrion

Hola a todos!!

En el ejercicio 6.4.ii. he utilizado otra forma para que no se repita la última linea del fichero:

#include <stdio.h>
#include <stdlib.h>

struct{
   char nombre[80], ciudad[40];
   int edad;
}datos[10];

int i;
char lectura[80];

main(){
   
   FILE* fichero;
   fichero = fopen("gente.dat", "wt");
   
   for (i=0; i<10; i++){
       printf("\n\tFicha %d\n\n", i+1);
       printf("Introduzca nombre: ");
       scanf(" %[^\n]", datos[i].nombre);
       printf("Introduzca edad: ");
       scanf(" %d", &datos[i].edad);
       printf("Introduzca ciudad: ");
       scanf(" %[^\n]", datos[i].ciudad);
       
       fprintf(fichero, "\n\tFicha %d\n\nNombre: %s\nEdad: %d\nCiudad: %s\n", i+1,
               datos[i].nombre, datos[i].edad, datos[i].ciudad);
   }
   
   fclose(fichero);
   
   fichero = fopen("gente.dat", "rt");
   
   if (fichero == NULL){
       printf("No existe el fichero");
       exit(1);
   }
   
   printf("Los datos del fichero: \n");
   
   while (!feof(fichero)){
       fscanf(fichero," %[^\n]", lectura);
       if (!feof(fichero))
           printf("%s\n", lectura);
   }

   fclose(fichero);
   
   return 0;
}

Creo que ya lo voy pillando pero me gustaría saber porque tengo que condicionarlo con if si ya lo he hecho con while.

Gracias


05-Jul-2012 03:57
Pablo Rampa

Hola, Rudi:
  Gracias por la ayudadota que me diste con el programa que pide un nombre
  y lee el archivo nombrado. Me encontraba paralizado, sin saber que hacer.
 
  Aquí te comento tu ejercicio:
       
//Ahora el ejercicio que yo he hecho (6.3.i):

//Escribir y leer fichero
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

main()
{
  FILE* fichero;
  char frase[80], line[81];
 
  fichero = fopen("frases.txt", "wt");

  printf("Escribe un texto\n");
  printf("y para finalizar pulsa \"ENTER\":\n\n");
 
  do
  {
     gets(frase);
        if (strcmp(frase, "") == 0)
           break;
        fprintf(fichero, "%s\n", frase);
  }
  while (strcmp(frase, "") != 0);
 
  fclose(fichero);
 
  fichero = fopen("frases.txt", "rt");
  if (fichero == NULL)
  {
     printf("No existe el fichero\n");
     exit(1);
  }
  while (!feof(fichero))
  {
     fgets(frase, 80, fichero);
     if (!feof(fichero))        // Gracias a esto no reptite la última linea,
                                // porque verificamos eof antes que imprima
        //puts(frase);         // la última línea. Con puts tenemos doble espacio.
        fputs(frase, stdout); // Prueba con ambas.                              
  }                            
  fclose(fichero);            
  getchar();
  return 0;
}

/*Esto lo aprendí investigando por google pero no se porque funciona.

Hay dos cosas que no entiendo:
   
1 - ¿Que es lo que hace " fputs(frase,stdout); "?

    R/ fputs coloca el contenido defrase en el flujo de salida estandar
    (buffer de salida estandar) que corresponde al monitor.
2 - ¿Porque no es necesario imprimir la linea en el programa con " puts(frase); "?
    Ya que si lo hago me repite todas las lineas.
   
    R/ Lo usual es usar puts y no es necesario fputs. Con puts imprime a doble
    espacio, sería interesante averiguar por qué.

Gracias, de nuevo.
Realmente no me explico por qué hay que volver a verificar el
eof.
       .....Saludos!


08-Jul-2012 10:46
Nacho Cabanes (+83)

- Con "puts" imprime a doble espacio porque "puts" avanza de línea tras escribir, y cuando lees con "fgets", el avance de línea original queda como parte de la cadena. Las alternativas son

a) Usar "printf" en vez de puts, sin terminar con un \n (o "fputs" en stdout, pero me parece más enrevesado)

b) Modificar la cadena leída, para eliminarle el avance de línea final.


- Hay que volver a verificar el "eof" porque estamos haciendo la lectura después de haber comprobado, y damos por sentado que sí hemos podido leer. Generalmente el valor de "eof" se actualiza tras cada nueva lectura, así que una forma más segura de conseguir lo mismo sería:

   fgets(linea, 80, fichero);
   while (! feof(fichero)) {      
     puts(linea);
     fgets(linea, 80, fichero);
   }

Es decir, intentamos leer, si lo hemos conseguido mostramos el valor, y finalmente intentamos una nueva lectura.






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