No me lee correctamente datos de un archivo, ayuda!

Iniciado por k3r00t, 5 Julio 2011, 18:59 PM

0 Miembros y 1 Visitante están viendo este tema.

k3r00t

Este es el caso, tengo un archivo de esta forma:

21
Shukra P
Io L
Aisa A
Sirio S
Mangala P
Alfa_Centauri S
Europa L
Guru P
Beta_Crucis S
Laquesis A
Ganimedes L
Cloto A
Vega S
Capella S
Atropos A
Shani P
Rigel S
Calisto L
Afrodita_Urania A
Budha P
Alfa_Crucis S


Leo el numero de cuerpos n que en este caso es 21 e inicio este ciclo para guardarlos en un vector de registro:

fscanf(pf,"%d",&n); 

for (i=1;i<=n;i++){   

fscanf(pf,"%s",planet_info[i-1].nombre);
fscanf(pf,"%c",planet_info[i-1].cod);

}


Donde planet_info es un vector de tipo cuerpos y cuerpos es un registro que contiene dos elementos, una cadena nombre y un char cod. El problema es que solo me almacena hasta Ganimedes y no me llega hasta el final. y la verdad no entiendo cual pueda ser el problema! el archivo abre y cierra perfectamente y el vector esta declarado para 200 posiciones. si me echan una mano seria de gran ayuda, saludos!

leogtz

#1
Prueba así:

fscanf(pf,"%d",&n);  
for (i=1;i<=n;i++)
fscanf(pf,"%s %c",planet_info[i-1].nombre, planet_info[i-1].cod);


La explicación de por qué falla es que con cafa fscanf() avanzas una línea, así que ibas avanzando de dos en dos.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

k3r00t

Cita de: Leo Gutiérrez. en  5 Julio 2011, 21:22 PM
Prueba así:

fscanf(pf,"%d",&n);  
for (i=1;i<=n;i++)
fscanf(pf,"%s %c",planet_info[i-1].nombre, planet_info[i-1].cod);


La explicación de por qué falla es que con cafa fscanf() avanzas una línea, así que ibas avanzando de dos en dos.

Si se me había ocurrido esa idea pero me lanza lo mismo! lo que me imprime es esto:

Citar21
Shukra P
Io L
Aisa A
Sirio S
Mangala P
Alfa_Centauri S
Europa L
Guru P
Beta_Crucis S
Laquesis A
Ganimedes

y pense en eso que me dijiste porque contando hasta la palabra Ganimedes hay exactamente 21, y puse 42 en el archivo y si me los lee completo pero necesito ese n intacto, que sera?

leogtz

#3
He probado lo siguiente y me funciona, miralo:

#include <stdio.h>

struct _cuerpos
{
   char nombre[80];
   char cod;
} cuerpos[21]; /* Esto puede variar así que es mejor usar un arreglo dinámico de estructuras */

int main(void)
{
   FILE *pf = fopen("file.txt", "r");

   int n;
   char string[80], c;

   fscanf(pf, "%d", &n);
   printf("%d\n", n);

   unsigned i;

   for(i = 0; i < n; i++)
   {
       fscanf(pf, "%80s %c", cuerpos[i].nombre, &cuerpos[i].cod);
       printf("[%s][%c]\n", cuerpos[i].nombre, cuerpos[i].cod);
   }

   fclose(pf);
   return 0;

}


file.txt es el mismo archivo que has puesto.


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

struct _cuerpos
{
   char nombre[80];
   char cod;
} *cuerpos;

int main(void)
{
   unsigned n, i;
   FILE *fp = fopen("file.txt", "r");
   if(fp == NULL)
   {
       perror("Error abriendo archivo");
       exit(EXIT_FAILURE);
   }

   fscanf(fp, "%d", &n);

   /* Crear el arreglo dinámico */
   cuerpos = malloc(sizeof(struct _cuerpos) * n);
   for(i = 0; i < n; i++)
   {
       fscanf(fp, "%s %c", cuerpos[i].nombre, &cuerpos[i].cod);
       printf("[%s][%c]\n", cuerpos[i].nombre, cuerpos[i].cod);
   }

   free(cuerpos);

   fclose(fp);
return EXIT_SUCCESS;
}
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

rir3760

La recomendación dada por Leo (uso de "%s %c") debe solucionar el problema.


La causa del error es la siguiente, al utilizar estas dos llamadas:
fscanf(pf,"%s",planet_info[i-1].nombre);
fscanf(pf,"%c",planet_info[i-1].cod);


En la primera iteracion del bucle la primera llamada lee una palabra y el problema viene con la segunda: "%c" lee el primer carácter que encuentre sin ignorar el espacio blanco (espacio, tabulador, avance de linea, etc.). Ese es el espacio que separa la palabra del carácter.

En la segunda iteracion del bucle la primera llamada a función con "%s" lee el carácter y la segunda llamada con "%c" lee el avance de linea.

Esa es la razón por la cual debes doblar el numero de registros.


Para evitarlo basta con utilizar "%s %c" ya que esta lee una palabra ("%s"), descarta el espacio (" ")y por ultimo lee el carácter ("%c").

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language