Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] Error con el buffer en archivo de texto

Estas en el tema de Error con el buffer en archivo de texto en el foro de C/C++ en Foros del Web. Buenas noches amigos de forosweb xD por aqui estoy de nuevo pidiendo de su ayuda, bueno estoy creando un pequeño programa para agregar, ver y ...
  #1 (permalink)  
Antiguo 21/03/2014, 20:03
 
Fecha de Ingreso: enero-2014
Mensajes: 47
Antigüedad: 10 años, 11 meses
Puntos: 0
Error con el buffer en archivo de texto

Buenas noches amigos de forosweb xD por aqui estoy de nuevo pidiendo de su ayuda, bueno estoy creando un pequeño programa para agregar, ver y eliminar deportistas de un programa, estoy apenas empezandolo, pero en la parte de leer, lee los datos del archivo sin problema pero me imprime el ultimo campo dos veces les muestro el ejemplo:



xD sorry por lo feo del tabuleo tengo que ver como arreglarlo xD, pues bien como pueden observar se repite el codigo 1 1, es decir siempre se repite el codigo dos veces del ultimo campo agregado, limpie el buffer con fflush(stdin) despues del fscanf pero me da el mismo error dejo el codigo a ver que consejo podrian darme gracias de antemano .

Código C:
Ver original
  1. void leer(void)
  2. {
  3.      
  4.      FILE *archivo;
  5.      char temp[80];
  6.      int a;
  7.      
  8.    
  9.  
  10.      archivo=fopen("Lista.dat","r");
  11.      if (archivo==NULL)
  12.      {
  13.                        printf("ERROR");
  14.                        }
  15.                        
  16.                        else
  17.                        {
  18.                            system("cls");
  19.                            printf("NOMBRE\t\t");
  20.                             printf("APELLIDO\t\t");
  21.                              printf("EDAD\t\t");
  22.                               printf("DEPORTE\t\t");
  23.                                printf("CODIGO\t\t\n");
  24.                                       while (!feof(archivo))
  25.                                       {
  26.                                             fscanf(archivo,"%s",&temp);
  27.                            
  28.                                             printf("%s \t\t",temp);
  29.                                            
  30.                                             }
  31.                                      
  32.                        }
  33.  
  34.                        getch();
  35.                   fclose(archivo);
  36.                
  37.              
  38.    
  39. }
  #2 (permalink)  
Antiguo 22/03/2014, 05:06
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 12 años, 4 meses
Puntos: 83
Respuesta: Error con el buffer en archivo de texto

Una cosa, que formato tiene el lista.dat? Es decir, como guardas los datos que quieres leer despues? Independientemente de como lo tengas haz el ciclo sin basarte en el feof sino en el estado de la funcion, eso sirve para saber que has llegado al final del archivo y como control de errores. Esto se implementa con el valor de retorno de fscanf:

Si no hay error: retorna el nº de entidades leidas; en tu caso las entidades son %s, es decir que hay una ejecucion positiva siempre que fscanf retorna 1
Si hay error:retorna un numero menor al de las entidades indicadas (p.ejemplo si indicas "%d %f" y retorna 1 cuando deberia retornar 2, o si retorna 0, o si retorna -1). Si la causa es que no hubo posibilidad de encontrar formatos compatibles simplemente retorna el nº de entidades encontradas segun el formato; si se llego al final del archivo marcará feof, y si hubo cuanquier otro error marcará ferror.

Puesto en codigo sería algo asi:

Código C:
Ver original
  1. while(1) {
  2.     if(fscanf(archivo, "%s", temp) == 1) {
  3.         //lectura correcta
  4.         printf("%s\t", temp);
  5.     }
  6.     else {
  7.         //control de errores
  8.         if(feof(archivo)) {
  9.             //final del archivo
  10.             //no es un error pero se trata como tal
  11.         }
  12.         else if(ferror(archivo)) {
  13.             printf("Se produjo un error de acceso");
  14.         }
  15.         else {
  16.             printf("Se produjo un error inesperado");
  17.         }
  18.        
  19.         //salgo del bucle
  20.         break;
  21.     }
  22. }

Solo una cosa a tener en cuenta: el while(1) es un bucle infinito, tienes que tenerlo controlado en todo momento.

Cuando entras al 'else' de control de errores siempre tienes que finalizar el bucle infinito, de lo contrario no puedes asegurar que seguiras controlandolo.

Tal como ves, es una buena practica hacer todas las comprovaciones de error.

Otra cosa: ya que en tu otro post trabajabas con estructuras, porque no guardas las estructuras directamente al archivo para despues leerlas en una sola vez? Una vez has leido la estructura muestras cada campo por pantalla tal como quieras.

Saludos
vosk
  #3 (permalink)  
Antiguo 24/03/2014, 21:18
 
Fecha de Ingreso: enero-2014
Mensajes: 47
Antigüedad: 10 años, 11 meses
Puntos: 0
Respuesta: Error con el buffer en archivo de texto

Hola vosk gracias por tu pronta repuesta llena de observaciones constructivas, estuve varios dias sin conectarme y he seguido al pie de la letra tus indicaciones y respondo tus preguntas el formato en que tengo el archivo .Dat es puro texto con un salto de linea luego de cada campo es eso lo que preguntabas ?

Una duda vosk, en varios campos uso el %d como en edad y codigo pero igual al hacer fprint me lo lee como cadena de texto, como dices lo del retorno del fscanf, es decir como se cuando me leera entero es decir cuando me devolvera el fscanf 2, no se si me explique, por otro lado si colocara como condicion en el if de la linea 2,
Código C:
Ver original
  1. if(fscanf(archivo, "%s", temp) == 2) {
el numero 2 como condicion para leer la cadena de texto debo tener dos argumentos ejem: %d %f.

Luego me preguntas que trabaje con estructuras y correctamente, guardo la estructura directamente al archivo de esta forma:

Código C:
Ver original
  1. printf("Cuantos atletas desea agregar \n");
  2. scanf("%d",&c);
  3.  
  4.     for (i=0;i<c;i++)
  5.     {
  6.     system("cls");
  7.     puts("Nombre ");
  8.     scanf("%s",&dat[i].nombre);
  9.     puts("Apellido ");
  10.     scanf("%s",&dat[i].apellido);
  11.     puts("Edad ");
  12.     scanf("%d",&dat[i].edad);
  13.     puts("Deporte ");
  14.     scanf("%s",&dat[i].deporte);
  15.     puts("Codigo ");
  16.     scanf("%d",&dat[i].codigo);
  17.    fprintf(archivo,"%s\n%s\n%d\n%s\n%d\n\n",dat[i].nombre,dat[i].apellido,dat[i].edad,dat[i].deporte,dat[i].codigo);
  18.    }
  19.    fclose(archivo);
  20. }
Gracias por tu ayuda y asi me ha quedado el codigo luego de seguir tus instrucciones:
Código C:
Ver original
  1. void leer(void)
  2. {
  3.      
  4.      FILE *archivo;
  5.      char temp[80];
  6.      int a;
  7.      int x,y,con,b;
  8.      x=1;
  9.      y=2;
  10.      b=2;
  11.      con=0;
  12.      
  13.    
  14.  
  15.      archivo=fopen("Lista.dat","r");
  16.      if (archivo==NULL)
  17.      {
  18.                        printf("ERROR");
  19.                        }
  20.                        
  21.                        else
  22.                        {
  23.                            system("cls");
  24.                            printf("NOMBRE\t\t");
  25.                             printf("APELLIDO\t\t");
  26.                              printf("EDAD\t\t");
  27.                               printf("DEPORTE\t\t");
  28.                                printf("CODIGO\t\t\n");
  29.                                  
  30.                                      
  31.                        }
  32.                        while(1)
  33.                        {
  34.                                if (fscanf(archivo,"%s",temp)==1)
  35.                                {
  36.                                con++;
  37.                                gotoxy(x,y);printf("%s ",temp);
  38.                                x+=16 ;
  39.                                                 if(con==5)
  40.                                              {
  41.                                              printf("\n");
  42.                                              con=0;
  43.                                              x+=1;
  44.                                              y+=b;
  45.  
  46.                                              }
  47.                                }
  48.                                
  49.                                      else
  50.                                      {
  51.                                          if(feof(archivo))
  52.                                          {
  53.                                                           printf("\n\n\nFINAL DEL ARCHIVO");
  54.                                                           }
  55.                                                           else if (ferror(archivo))
  56.                                                           {
  57.                                                                printf("Error de acceso");
  58.                                                                }
  59.                                                                else
  60.                                                                {
  61.                                                                    printf("Error inesperado");
  62.                                                                    }
  63.                                      break;
  64.                                      }
  65.                                
  66.                        }
  67.  
  68.                        getch();
  69.                   fclose(archivo);
  70.                
  71.              
  72.    
  73. }
y otra pregunta hay que aprovechar, xD xq rayos se imprimia un campo de mas ? al colocar el codigo de la primera manera?
  #4 (permalink)  
Antiguo 24/03/2014, 21:45
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 11 años, 2 meses
Puntos: 38
Respuesta: Error con el buffer en archivo de texto

No sera por que en la ultima linea no has puesto un '\n' (ENTER).
Algunas funciones leen toda la linea hasta encontrar \n, y si justo en la ultima linea no pones el \n me parece que repite muchas veces esta ultima linea.
Me parece haber contestado a alguien hace poco con el mismo problema O.o
pensando bien el error puede ser por esa funcion getch(); que tienes al final.
No uso esta libreria y tu código no me ha imprimido nada doble al final
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <windows.h>
  3.  
  4.  
  5.  
  6. int main () {
  7.  
  8.     FILE * archivo;
  9.     char temp[80];
  10.     int a;
  11.     int x, y, con, b;
  12.     x = 1;
  13.     y = 2;
  14.     b = 2;
  15.     con = 0;
  16.    
  17.    
  18.    
  19.     archivo = fopen ( "Lista.dat", "r" );
  20.    
  21.     if ( archivo == NULL ) {
  22.         printf ( "ERROR" );
  23.     }
  24.    
  25.     else {
  26.         system ( "cls" );
  27.         printf ( "NOMBRE\t\t" );
  28.         printf ( "APELLIDO\t\t" );
  29.         printf ( "EDAD\t\t" );
  30.         printf ( "DEPORTE\t\t" );
  31.         printf ( "CODIGO\t\t\n" );
  32.        
  33.        
  34.     }
  35.    
  36.     while ( 1 ) {
  37.         if ( fscanf ( archivo, "%s", temp ) == 1 ) {
  38.             con++;
  39.             printf ( "%s ", temp );
  40.             x += 16 ;
  41.            
  42.             if ( con == 5 ) {
  43.                 printf ( "\n" );
  44.                 con = 0;
  45.                 x += 1;
  46.                 y += b;
  47.                
  48.             }
  49.         }
  50.        
  51.         else {
  52.             if ( feof ( archivo ) ) {
  53.                 printf ( "\n\n\nFINAL DEL ARCHIVO" );
  54.             } else
  55.                 if ( ferror ( archivo ) ) {
  56.                     printf ( "Error de acceso" );
  57.                 } else {
  58.                     printf ( "Error inesperado" );
  59.                 }
  60.                
  61.             break;
  62.         }
  63.        
  64.     }
  65.    
  66.  
  67.     fclose ( archivo );
  68.     return 0;
  69.    
  70.    
  71. }
Este es el código... Como ves paso de rosca del conio este ><

Eso es lo que tenia en la Lista.dat:
Código txt:
Ver original
  1. pepe
  2. ceporro
  3. 47
  4. ninguno
  5. 007

Efectivamente habia un problema parecido con la función getline() que había postado aquí:
http://www.forosdelweb.com/f96/abrir...texto-1094279/
Echa un ojo si te interesa ^^

Última edición por vangodp; 24/03/2014 a las 22:06
  #5 (permalink)  
Antiguo 26/03/2014, 05:50
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 12 años, 4 meses
Puntos: 83
Respuesta: Error con el buffer en archivo de texto

@TriN: "...y otra pregunta hay que aprovechar, xD xq rayos se imprimia un campo de mas ?..."

Bueno, realmente se imprimia un campo de mas porque no hacias las comprovaciones correctas. Pongo tu primer codigo otra vez (el que no funciona):

Código C:
Ver original
  1. while(!feof(archivo)) {
  2.     fscanf(archivo,"%s",&temp);
  3.     printf("%s \t\t",temp);
  4. }


Tal como te comente fscanf retorna el numero de entidades leidas (y copiadas en los bufers proporcionados), en este caso pides 1 entidad %s y proporcionas un char*, por lo tanto debes esperar que fscanf retorne 1 y copie algo en el char*. En la ultima ciclo, cuando duplica el ultimo campo, fscanf retorna 0 y no copia nada en el char*, pero como no compruebas el valor de retorno presupones que está leyendo algo nuevo y muestras lo ultimo que habia copiado en el bufer (es decir duplicas el ultimo campo).

Puedes aplicar la modificacion sobre tu primer codigo e ira igual de bien:

Código C:
Ver original
  1. while(!feof(archivo)) {
  2.     if(fscanf(archivo,"%s", &temp) == 1) {
  3.         printf("%s \t\t", temp);
  4.     }
  5.     else {
  6.         if(feof(archivo)) {
  7.             //final de archivo
  8.         }
  9.         else if (ferror(archivo)) {
  10.             //error conocido
  11.         }
  12.         else {
  13.             //error inesperado
  14.         }
  15.     }
  16. }


Con esto puedes ver la importancia de los valores de retorno de las funciones y la importancia de las comprovaciones de seguridad.

Saludos
vosk
  #6 (permalink)  
Antiguo 26/03/2014, 06:53
Avatar de vangodp  
Fecha de Ingreso: octubre-2013
Mensajes: 934
Antigüedad: 11 años, 2 meses
Puntos: 38
Respuesta: Error con el buffer en archivo de texto

muy buena... que fiera eres vosk
  #7 (permalink)  
Antiguo 26/03/2014, 08:33
 
Fecha de Ingreso: enero-2014
Mensajes: 47
Antigüedad: 10 años, 11 meses
Puntos: 0
Respuesta: Error con el buffer en archivo de texto

Wuaow mas claro imposible, muchisimas gracias por su ayuda ya entendi claramente y bueno a seguir practicando...

Etiquetas: buffer, int, programa
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 07:10.