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

Leer de Fichero

Estas en el tema de Leer de Fichero en el foro de C/C++ en Foros del Web. Hola a tod@s !!! A ver tengo un problema para leer de fichero y no se como solucionarlo !! Imaginen que en el fichero tengo ...
  #1 (permalink)  
Antiguo 25/01/2012, 09:43
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Leer de Fichero

Hola a tod@s !!!

A ver tengo un problema para leer de fichero y no se como solucionarlo !!

Imaginen que en el fichero tengo esto:
sad12### -34.5666xxxx 99.01 asdasd7asd

Pues como puedo hacer para extraer los numeros (double) tal que quede asi:
12.0, -34.5666, 99.01 y 7.0

No se como hacerlo, lo he intentando con el fgetc pero sin exito

A ver si me pueden echar una mano y gracias !!
  #2 (permalink)  
Antiguo 25/01/2012, 10:47
 
Fecha de Ingreso: agosto-2008
Mensajes: 240
Antigüedad: 15 años, 7 meses
Puntos: 6
Respuesta: Leer de Fichero

Hola,

¿has probado con fscanf()?

Un saludo
  #3 (permalink)  
Antiguo 25/01/2012, 10:56
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Cita:
Iniciado por gonzo13 Ver Mensaje
Hola,

¿has probado con fscanf()?

Un saludo
Hola !! Si tambien probe con fscanf(), pero como tengo que quedarme con los negativos tambien ( -34.5666 ) pues la mejor opcion (creí...) que era fgetc(), pero la verdad es que no se como hacerlo

¿Alguna sugerencia? Graciass !!
  #4 (permalink)  
Antiguo 25/01/2012, 11:36
 
Fecha de Ingreso: diciembre-2011
Ubicación: CABA
Mensajes: 433
Antigüedad: 12 años, 3 meses
Puntos: 94
Respuesta: Leer de Fichero

Hola johncapi! esta dificil lo que queres hacer, pero todo sale. La funcion atof() convierte la porcion inicial de una cadena a double y devuelve ese valor, ejemplo:
Código C:
Ver original
  1. char arr[]="-14asb$$";
  2. variable=atof(arr);
  3. printf("%lf\n",variable);

Se va a imprimir -14.000000

Ahora bien lo complicado es como detectas en tu cadena "sad12### -34.5666xxxx 99.01 asdasd7asd" los numeros??. Te recomiendo que primero obtengas esa linea del archivo con fgets y luego recorras la cadena hasta que encuentres un numero, Es decir tendrias que recorrer tu cadena hasta encontrar el puntero que apunte a "12### -34.5666xxxx 99.01 asdasd7asd"... Fijate si se te ocurre algo sino segui preguntando

Prototipo de la funcion atof: double atof(char * ptr)
Debes incluir el header <stdlib.h> para que funcione correctamente

Saludos
  #5 (permalink)  
Antiguo 25/01/2012, 11:45
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Cita:
Iniciado por cesar_casla Ver Mensaje
Hola johncapi! esta dificil lo que queres hacer, pero todo sale. La funcion atof() convierte la porcion inicial de una cadena a double y devuelve ese valor, ejemplo:
Código C:
Ver original
  1. char arr[]="-14asb$$";
  2. variable=atof(arr);
  3. printf("%lf\n",variable);

Se va a imprimir -14.000000

Ahora bien lo complicado es como detectas en tu cadena "sad12### -34.5666xxxx 99.01 asdasd7asd" los numeros??. Te recomiendo que primero obtengas esa linea del archivo con fgets y luego recorras la cadena hasta que encuentres un numero, Es decir tendrias que recorrer tu cadena hasta encontrar el puntero que apunte a "12### -34.5666xxxx 99.01 asdasd7asd"... Fijate si se te ocurre algo sino segui preguntando

Prototipo de la funcion atof: double atof(char * ptr)
Debes incluir el header <stdlib.h> para que funcione correctamente

Saludos
Gracias por tu aporte cesar_casla !!!
Voy a intenetarlo a ver que me sale !! Gracias otra vez !!
  #6 (permalink)  
Antiguo 25/01/2012, 13:07
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Leer de Fichero

La cantidad de numeros es fija siempre??
Sino podrias con fgets tomar la linea entera. Luego con un for convertir en espacio todo lo que no sea numero punto o signo:

Código C:
Ver original
  1. for(i=0;i< strlen(cadena); i++)
  2.      if ( ~ (  (cadena[i] >= '0'  && cadena[i] <= '9' ) || cadena[i] == '.'  || cadena[i] == '-')   )  
  3.              cadena[i ] = ' ' ;

Ahora que solo tienes los numeros puedes hacer sscanf cuantas veces quieras.
  #7 (permalink)  
Antiguo 25/01/2012, 13:07
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Bueno, lo he intentando de varias formas, pero lo que me "funciona bien" es esto:
Código:
 char cadena[100];
     while (feof(fich) == 0)
        {
                fgets(cadena,100,fich);
                printf("%s",cadena);
        }
        
    
    for(i;i<strlen(cadena);i++)
        if(cadena[i] !='1' && cadena[i] !='2' && cadena[i] !='3' && cadena[i] !='4' && cadena[i] !='5' && cadena[i] !='6' && cadena[i] !='7' && cadena[i] !='8' && cadena[i] !='9' && cadena[i] !='0' && cadena[i] !='-' && cadena[i] !='.')
            cadena[i] = -1;
printf("\n%s",cadena);


Este pequeño metodo imprime:
1º printf = sad12### -34.5666xxxx 99.01 asdasd7asd
2º printf =    12    -34.5666     99.01       7
Bueno, este apaño no se si es correcto, pero ahora lo que tengo que hacer es guardar esos 4 numeros en un vector de 4 posiciones. Eso no se si es posible hacerlo directamente.
¿Sugerencias?
  #8 (permalink)  
Antiguo 25/01/2012, 13:10
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Cita:
Iniciado por sam90 Ver Mensaje
La cantidad de numeros es fija siempre??
Sino podrias con fgets tomar la linea entera. Luego con un for convertir en espacio todo lo que no sea numero punto o signo:

Código C:
Ver original
  1. for(i=0;i< strlen(cadena); i++)
  2.      if ( ~ (  (cadena[i] >= '0'  && cadena[i] <= '9' ) || cadena[i] == '.'  || cadena[i] == '-')   )  
  3.              cadena[i ] = ' ' ;

Ahora que solo tienes los numeros puedes hacer sscanf cuantas veces quieras.
No, la cantidad de numeros puede variar, asi como la de "basura". Es decir, puede haber tantos caracteres (# @ % & ¬) como se desee.
Sin embargo el caracter "." si que sirve al igual que "-" de negativo.
  #9 (permalink)  
Antiguo 25/01/2012, 13:16
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Modifico el codigo para que sea un poco mas limpio !!
Código:
 for(i=0;i< strlen(cadena); i++)
         if (  (cadena[i] < '0'  || cadena[i] > '9' )  && (cadena[i] != '.' &&  cadena[i] !='-') )  
                 cadena[i ] = -1 ;
Ahora el problema es "tratarlo como numero" para introducirlo en un vector de 4 posiciones de tipo Double
  #10 (permalink)  
Antiguo 25/01/2012, 14:39
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Leer de Fichero

Me estas diciendo que la cantidad de numeros no es fijas y me hablas de cuatro numeros todo el tiempo... Yo no habla de digito eso se sobre entiende en casi todo los ejemoplos.

Si son cuatro los numeros que necesitas puedes hacer como te dije antes:

sscanf(cadena,"%f %f %f %f",numero[0],numero[1],numero[2],numero[3]);

sscanf hace lo mismo que el fscanf o el scanf nada mas que este lee desde una variable y no desde un archivo o desde el teclado.

Saludos.
  #11 (permalink)  
Antiguo 25/01/2012, 15:02
 
Fecha de Ingreso: diciembre-2011
Ubicación: CABA
Mensajes: 433
Antigüedad: 12 años, 3 meses
Puntos: 94
Respuesta: Leer de Fichero

Lo unico que se me sigue ocurriendo por ahora es con la funcion atof como te mencione anteriormente. te dejo como seria(es una version sin q tengas q modificar la cadena que extraes del archivo):
Código C:
Ver original
  1. int flag=1,i,j,k;
  2. char *arr="asddf-13$%&2ku12.6";
  3. float numeros[MAX];
  4. for(i=0;arr[i];i++) // el for termina cuando llega al final de la cadena
  5. {
  6. if( !isdigit(arr[i] && arr[i]!='-' && arr[i]!='.') {
  7.    flag=1;
  8.    continue;
  9.    }
  10. if(arr[i]=='-' || (isdigit(arr[i]) && flag))
  11. {
  12.    numeros[j]=atof( arr+i );
  13.    j++;
  14.    flag=0;
  15. }
  16. }// fin del for
  17.  
  18. //para imprimir los valore
  19. for(k=0;k<j;k++)
  20.     printf("%f\n",numeros[k]);

Explicacion: el primer if comprueba q arr[i] no se un numero que no sea un '-' y un '.' si cumple todo eso entra al if hace flag=1 y ejecuta continue ¿para que continue? solo para evitar que no evalue el segundo if pero si queres sacalo
El segundo if comprueba que arr[i] sea un '-' o sea un numero y flag sea 1, si es asi ejecuta atof,guarda el numero y pone a flag en 0 ¿por que en 0? para evitar que vuelva a entrar en el if, de esta manera evitamos que atof guarde numero erroneos
Sino se entiende bien el codigo pregunta :)

SAludos
  #12 (permalink)  
Antiguo 25/01/2012, 15:09
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Cita:
Iniciado por sam90 Ver Mensaje
Me estas diciendo que la cantidad de numeros no es fijas y me hablas de cuatro numeros todo el tiempo... Yo no habla de digito eso se sobre entiende en casi todo los ejemoplos.

Si son cuatro los numeros que necesitas puedes hacer como te dije antes:

sscanf(cadena,"%f %f %f %f",numero[0],numero[1],numero[2],numero[3]);

sscanf hace lo mismo que el fscanf o el scanf nada mas que este lee desde una variable y no desde un archivo o desde el teclado.

Saludos.
Quizas yo no te entendi o me explique mal, a ver...
Son 4 numeros porque en el fichero hay actualmente:
sad12### -34.5666xxxx 99.01 asdasd7asd
1º Numero = 12
2º Numero = -34.5666
3º Numero = 99.01
4º Numero = 7

Pero si en el fichero hubiese
sad12### -34.5666xxxx 99.01 asdasd7asd78&$%&4xx
Habria:
1º Numero = 12
2º Numero = -34.5666
3º Numero = 99.01
4º Numero = 7
5º Numero = 78
6º Numero = 4

Perdon por la confusion !!
  #13 (permalink)  
Antiguo 25/01/2012, 15:34
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Código:
1º printf = sad12### -34.5666xxxx 99.01 asdasd7asd
2º printf =    12    -34.5666     99.01       7
El problema que tengo ahora es almacenar esos numeros en variables, porque al haber espacios no se guardalos en esas variables.
No puedo eliminar todos los espacios porque tengo que diferenciar el primer digito del segundo, el segundo del tercero, etc
He probado con sscanf, pero no lo consigo
¿Alguna idea?
PD: He probado tu codigo @cesar_casla (modificandolo) y tampoco me funciona :(
  #14 (permalink)  
Antiguo 25/01/2012, 16:26
 
Fecha de Ingreso: diciembre-2011
Ubicación: CABA
Mensajes: 433
Antigüedad: 12 años, 3 meses
Puntos: 94
Respuesta: Leer de Fichero

q raro! lo he probado y funciona bien. Te paso algunas cosas q no aclare:
MAX es un define, pone por ejemplo #define MAX 5
Para usar la funcion isdigit() tenes que incluir #include <ctype.h>
Al declarar la variable j me faltaba inicializarla en cero, j=0;

Fijate si con eso t anda, sino subi el codigo completo si podes

Saludos
  #15 (permalink)  
Antiguo 25/01/2012, 16:32
 
Fecha de Ingreso: abril-2010
Ubicación: Rosario
Mensajes: 1.850
Antigüedad: 14 años
Puntos: 228
Respuesta: Leer de Fichero

Para empezar no asignes el -1 cuando queres sacar caracteres:
cadena[i ] = -1 ;

Pone esto: cadena[i ] = ' ' ; // fijate que son comillas simples y un espacio.

Código C++:
Ver original
  1. i = 0;
  2. while (sscanf(cadena,"%f",numero[i]) == 1 ) i++;

En este momento no estoy en mi Pc para probarlo...pero podria ser el camino.
  #16 (permalink)  
Antiguo 25/01/2012, 17:52
 
Fecha de Ingreso: agosto-2008
Mensajes: 240
Antigüedad: 15 años, 7 meses
Puntos: 6
Respuesta: Leer de Fichero

Hola,

creo que tienes que leer la cadena dos veces. Primero tendrías que incrementar un contador para averiguar la cantidad de números que tienes que almacenar y luego solicitar memoria para dicha cantidad de valores.

Un saludo.
  #17 (permalink)  
Antiguo 25/01/2012, 23:37
 
Fecha de Ingreso: febrero-2003
Ubicación: D.F.
Mensajes: 163
Antigüedad: 21 años, 2 meses
Puntos: 22
Respuesta: Leer de Fichero

En este caso es conveniente utilizar strpbrk y strtod.
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int main(){
  6.     char str[] = "sad12### -34.5666xxxx 99.01 asdasd7asd";
  7.     char key[] = "0123456789-+.";
  8.     double x;
  9.     char *pEnd = str;
  10.     char *pStart = strpbrk (pEnd, key);
  11.     while(pStart){
  12.         x = strtod(pStart, &pEnd);
  13.         if(pStart != pEnd)printf("%f\n", x);
  14.         else pEnd++;
  15.         pStart = strpbrk (pEnd, key);
  16.     }
  17.     return 0;
  18. }
  #18 (permalink)  
Antiguo 26/01/2012, 05:17
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Cita:
Iniciado por fightmx Ver Mensaje
En este caso es conveniente utilizar [URL="http://www.cplusplus.com/reference/clibrary/cstring/strpbrk/"]strpbrk[/URL] y [URL="http://www.cplusplus.com/reference/clibrary/cstdlib/strtod/"]strtod[/URL].
Código C:
Ver original
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4.  
  5. int main(){
  6.     char str[] = "sad12### -34.5666xxxx 99.01 asdasd7asd";
  7.     char key[] = "0123456789-+.";
  8.     double x;
  9.     char *pEnd = str;
  10.     char *pStart = strpbrk (pEnd, key);
  11.     while(pStart){
  12.         x = strtod(pStart, &pEnd);
  13.         if(pStart != pEnd)printf("%f\n", x);
  14.         else pEnd++;
  15.         pStart = strpbrk (pEnd, key);
  16.     }
  17.     return 0;
  18. }
Estas 2 funciones no las conocia !!!! Han sido de gran utilidad !!!!
Ahora si solo quiero introducir ese double (x) en un vector (vec) solamente tengo que hacer una asignacion ?!?!?
Código:
while(pStart){
        x = strtod(pStart, &pEnd);
        vec[i] = x;
        i++;
        if(pStart != pEnd)printf("%f\n", x);
        else pEnd++;
  #19 (permalink)  
Antiguo 26/01/2012, 05:36
 
Fecha de Ingreso: enero-2012
Mensajes: 32
Antigüedad: 12 años, 3 meses
Puntos: 1
Respuesta: Leer de Fichero

Perfecto señores !!! Ya tengo el metodo funcionando a las mil maravillas !!!
Gracias a todos por su ayuda !!
+1 para todos !!!
Gracias otra vez !!!

Etiquetas: fichero
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 11:19.