/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Leer fichero .csv

 
      Índice del Foro elrincondelc.com -> C/C++ en General
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
mferril



Registrado: 03 Nov 2011
Mensajes: 7

MensajePublicado: 03/11/2011 9:14 am
Título: Leer fichero .csv

Buenas,
tengo un fichero .csv de datos separados por comas, en cada linea hay 10 datos diferentes.
ejemplo:

Est2,2011,11,02,00,10,madrid,-3.467,44.3578,17.0
Est1,2011,11,02,00,10,oviedo,-5.843,43.3607,15.2

me gustaría saber qué forma tengo de leer todas las lineas del fichero e identificar cada uno de los datos de cada linea.
este es mi código.

El problema es que solo me lee la primera linea.

#include <stdio.h>
#include <string.h>

int main()
{
FILE *fe,*fs;
char est[20],ano[20],mes[20],dia[20],hora[20],min[20],est1[20];
float lat,lon,t;
char linea[350];

char *token;


fe = fopen("est1.csv", "r");
fs=fopen("est2_s.txt","w");

while(fscanf(fe,"%[^\n]s",linea)!=feof(fe))
{


token = strtok(linea, ",");
strcpy(est,token);
token = strtok(NULL, ",");
strcpy(ano,token);
token = strtok(NULL, ",");
strcpy(mes,token);
token = strtok(NULL, ",");
strcpy(dia,token);
token = strtok(NULL, ",");
strcpy(hora,token);
token = strtok(NULL, ",");
strcpy(min,token);
token = strtok(NULL, ",");
strcpy(est1,token);
token = strtok(NULL, ",");
sscanf(token,"%f",&lat);
token = strtok(NULL, ",");
sscanf(token,"%f",&lon);
token = strtok(NULL, ",");
sscanf(token,"%f",&t);

fprintf(fs,"%s %s",est,est1);

}
fclose(fe);
fclose(fs);

return 0;

}

Muchas gracias por la ayuda,
es importante.
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 6586
Ubicación: Mexico

MensajePublicado: 03/11/2011 6:00 pm
Título:

El problema principal con tu programa es la condición del bucle, por alguna extraña razón utilizas:
Código:
while(fscanf(fe,"%[^\n]s",linea)!=feof(fe))

Honestamente eso no tiene pies ni cabeza, primero porque tratas de leer el carácter 's' (salvo un error en el archivo no es posible) y segundo por la comparación con "feof".

Lo primero que debes hacer es cambiar la condición del bucle a:
Código:
while(fscanf(fe, "%[^\n]%*c",linea) == 1)

Y verificar que con ella se lean correctamente todas las lineas del archivo. Una vez eso ya funcione correctamente pasas a la extracción de cada uno de los campos.

Un saludo
_________________
Memory never recaptures reality. Memory reconstructs. All reconstructions change the original, becoming external frames of reference that inevitably fall short.
--
Mentat Handbook
Volver arriba
mferril



Registrado: 03 Nov 2011
Mensajes: 7

MensajePublicado: 22/11/2011 5:55 am
Título: Leer fichero .csv

Cuando pensaba que ya estaba solucionado el problema,
me encuentro que cuando el fichero .csv le falta algun dato en alguna columna la funcion token no sabe que hacer para saltar.

este seria el codigo:
Querría que en la columna t, al no estar el dato le asigne a esta variable el valor 99.99

while(fscanf(fe, "%[^\n]%*c",linea) == 1)
{

token = strtok(linea, ",");
strcpy(est,token);
token = strtok(NULL, ",");
strcpy(ano,token);
token = strtok(NULL, ",");
strcpy(mes,token);
token = strtok(NULL, ",");
strcpy(dia,token);
token = strtok(NULL, ",");
strcpy(hora,token);
token = strtok(NULL, ",");
strcpy(min,token);
token = strtok(NULL, ",");
strcpy(est1,token);
token = strtok(NULL, ",");
sscanf(token,"%f",&lat);
token = strtok(NULL, ",");
sscanf(token,"%f",&lon);


token = strtok(NULL, ",");
if(token==NULL) t=99.99
else sscanf(token,"%f",&t);

fprintf(fs,"%s %f",est,t);

}
fclose(fe);
fclose(fs);

return 0;

}


me podeis seguir ayudando??

millon de gracias
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 6586
Ubicación: Mexico

MensajePublicado: 25/11/2011 10:16 pm
Título:

Lo primero que debes hacer es publicar un fragmento del archivo de datos, ello para tener una mejor idea del problema.

Si debes verificar si un campo esta vació, por ejemplo ante una entrada como esta:
Código:
a, b, c ,,,, x, y, z

La función strtok no te va a servir ya que esta se "salta" la secuencia de separadores ",,,,". Si el separador en cada linea de texto es único (al parecer en tu caso ',') puedes crear tu propia función en base a strchr (prototipo en <string.h>).

Un saludo
_________________
Memory never recaptures reality. Memory reconstructs. All reconstructions change the original, becoming external frames of reference that inevitably fall short.
--
Mentat Handbook
Volver arriba
rir3760



Registrado: 01 Oct 2004
Mensajes: 6586
Ubicación: Mexico

MensajePublicado: 27/11/2011 6:10 am
Título:

Otra opción es realizar el proceso de forma manual tomando nota de la posición inicial de cada token.

Un ejemplo sencillo (C estándar):
Código:
#include <stdio.h>
#include <stdlib.h>

#define MAX_TOKENS  10

int main(void)
{
   char test[] = "a,bb,ccc,,,,xxx,yy,z";
   int tok[MAX_TOKENS + 1] = {0};
   int num_tokens;
   int num_chars;
   int i;
   
   num_tokens = 0;
   i = 0;
   do {
      if ((test[i] == ',' || test[i] == '\0') && num_tokens < MAX_TOKENS)
         tok[++num_tokens] = i + 1;
   }while (test[i++] != '\0');
   
   for (i = 0; i < num_tokens; i++){
      printf("tok[%d] == ", i);
     
      if ((num_chars = tok[i + 1] - tok[i] - 1) == 0)
         puts("(null)");
      else
         printf("\"%.*s\"\n", num_chars, test + tok[i]);
   }
   
   return EXIT_SUCCESS;
}


Su salida es:
Código:
tok[0] == "a"
tok[1] == "bb"
tok[2] == "ccc"
tok[3] == (null)
tok[4] == (null)
tok[5] == (null)
tok[6] == "xxx"
tok[7] == "yy"
tok[8] == "z"


Sin embargo no contempla dos problemas: un token compuesto solo de espacio blanco y conversiones no validas (algo que al parecer tu programa requiere).

Un saludo
_________________
Memory never recaptures reality. Memory reconstructs. All reconstructions change the original, becoming external frames of reference that inevitably fall short.
--
Mentat Handbook
Volver arriba
      Índice del Foro elrincondelc.com -> C/C++ en General
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com