fscanf con .txt irregular

BEDI

Veamos, tengo un .txt con muchas filas a modo de base de datos. Por regla general cada fila esta dividida en 8 columnas. El problema es que algunas solo tienen 7 columnas

Yo habia echo este bucle while(fscanf( ___ ))==8) para ir leiendo todas las filas y meter cada fila en una estructura, pero claro, cuando llega a una fila donde solamente hay 7 columnas el programa coje como octavo dato el primero de la siguiente fila, se lia y ahi sale del bucle

Le he preguntado a mi profera de proramacion y me ha dicho que me mire el fscan lo haga del siguiente modo:

analizar por filas, escanear, cuando encuentre algo despues del espacio escanear... y cuando encuentr \n pasar a la siguiente estructura.

En nuestros apuntes no viene nada de esto, como puedo hacerlo?

Os pongo un ejemplo reducido para que podais operar, en tes caso habria nada mas que dos columnas con el mismo problema
typedef struct
{char a[20];
char b[20];
}t_columna;

A ver si una vez mas podeis auydar a un zokete como yo :)

maRc

En lugar de fscanf, usa fgetc, que lee únicamente un caracter, y te curras tu solito la función para meter los datos en la estructura.

Lees con el fgetc y lo va metiendo en un campo de la estructura. Cuando te encuentres un espacio, cambias de campo a rellenar. Cuando te encuentres un \n, cambias de estructura.

O con un fgets, que te lee hasta donde N bytes que le pasas o hasta fin de linea, y luego vas recorriendo lo que has leido buscando como antes, un espacio o un \n.

BEDI

ajam, gracias marc, esque mi profesora es la leche, me dice que lo haga asi y algunas de esas funciones no las hemos dado. Usare el getc e ire metiendo todo caracter a caracter :)

gF

Aquí tienes mi formula mágica, mi profesor de sistemas operativos llamo a otro profesor durante la entrevista de las prácticas solo para que viera este trozo mágico de código:

fscanf(f,"%[\n]\n",linea)

Lee del fichero f, todo hasta que encuentre \n (%[\n]) y pasa a la siguiente línea (el segundo \n) y lo leido lo almacena en linea.

BEDI

iepa gF eso es lo que andaba buscando, probare voy a hacer unas cuantas pruebas a ver que tal. En principio probare esto, aver que es lo que hace:
fscanf(f,"%s %s %s %s %s %s %s %s[\n]\n",a., a., ...)

Otra duda distinta que no he encontrado por google. Se que el fscanf devuelve el numero de conversiones satisfactorias, pero este bucle no me sale bien, que puede estar mal?

while(z!=EOF)
{z=fscanf(....)
if(z=8)
..
if(z=7)
..
}

Yo juraria que esto cada vez que pasa el bucle, mete en z el numero de conversiones satisfactorias, pero al comprobarlo con el debugger no es asi :s

gF

Te copio:

"La función fscanf retorna el número de datos de entrada asignados, que puede ser menor que ofrecido, incluso cero, en el caso de un error de asignación. Si un error de entrada ocurre antes de cualquier conversión, la función fscanf retorna el valor de la macro EOF."

La verdad es que no se muy bien como se comporta la función a la hora de devolver ese valor, ya que dice que pude devolver 0 en caso de un error de asignación y tu pones 8 %s cuando a veces hay 7, puede que eso produzca ese error. Yo de ti usaba fscanf tal como te la puse yo y luego procesaba la variable linea separando cada palabra usando como delimitador el caracter espacio.

T

gF eso no es flex?

Coge lo contrario a \n.

gF

Es C pero en flex tb se utilizan los modificadores para el analizador léxico ;) verdad?

javithelong

Nacie conoce fgets de aqui?

Con fgets lees una linea hasta \n y te la mete en un buffer. Y cuando lee fin de fichero te devuelve null, asi que puedes hacer un bucle en plan:

while (fgets (buffer, MAX_BUFFER, archivo) != NULL) {

// Aqui tu codigo con sscanf (buffer, "%s ...", ...);
}

Y lees el archivo entero en un minibucle ^^

EDIT: Para leer con sscanf te sirve, siempre y cuando sepas cuantos campos hay como máximo. Pones

n_campos = sscanf (buffer, "%s %s %s %s %s %s %s %s", campo1, campo2, campo3, campo4, campo5, campo6, campo7, campo8);
Y luego poniendo a 0 (o a un caracter que sepas que significa que no es válido) el resto de campos (te ayudas de 'n_campos') tienes todo resuelto

Saludos

BEDI

Bueno, al final entre todos conseguimos hacer lo que se pretende :)

Ya me sale perfectamente, haciendolo como dice javithelong. En mi post #5 pretendia hacer algo muy parecido pero sacando directamente z (n_campos) del fscanf, pero parece ser qu no funciona como deberia.

Lo dicho, todo un exito y ahora a seguir con mi programa

javithelong

Na, he puesto algo mal, y no me deja borrar el post, asi que lo edito y lo borro xD

Saludos

Usuarios habituales

  • javithelong
  • BEDI
  • gF
  • TuR0K2
  • maRc