| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
mferril
Registrado: 03 Nov 2011 Mensajes: 7
| Publicado: 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
| Publicado: 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
| Publicado: 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
| Publicado: 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
| Publicado: 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 | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|