2012-05-15 15 views
7

Tengo un valor que leo de un archivo y se almacena como un char *. El valor es un número monetario, #. ##, ##. ##, o ###. ##. Quiero convertir el carácter * en un número que puedo usar en los cálculos, lo he intentado con atof y strtod y simplemente me dan números de basura. ¿Cuál es la forma correcta de hacer esto y por qué lo estoy haciendo mal?Conversión de char * a flotación o doble

Esto es esencialmente lo que estoy haciendo, solo se lee el valor de char * de un archivo. Cuando imprimo las variables temp y ftemp son simplemente basura, números negativos gigantescos.

Otra edición:

Estoy funcionando exactamente esto en gcc

#include <stdio.h> 
int main() 
{ 
char *test = "12.11"; 
double temp = strtod(test,NULL); 
float ftemp = atof(test); 
printf("price: %f, %f",temp,ftemp); 
return 0; 

}

y mi salida es el precio: 3,344,336.000000, 3344336,000000

Editar: Aquí está mi código

if(file != NULL) 
    { 
     char curLine [128]; 
     while(fgets(curLine, sizeof curLine, file) != NULL) 
     {    
      tempVal = strtok(curLine,"|");   
      pairs[i].name= strdup(tempVal); 
      tempVal = strtok(NULL,"|"); 
      pairs[i].value= strdup(tempVal); 
      ++i; 
     } 
     fclose(file); 
    } 

    double temp = strtod(pairs[0].value,NULL); 
    float ftemp = atof(pairs[0].value); 
    printf("price: %d, %f",temp,ftemp); 

mi archivo de entrada es el nombre muy simple, pares de valores como esta:

NAME|VALUE 
NAME|VALUE 
NAME|VALUE 

con el valor siendo cantidades de dinero

resuelto: Gracias a todos, yo estaba usando% d en lugar de% f y didn' t tienen los encabezados correctos incluidos.

+4

El problema debe ser en otro lugar, el código que ha publicado es perfectamente válido y funciona. Por favor, muéstranos cómo lees tu archivo. –

+0

1. 'atof' devuelve' double' también: http://pubs.opengroup.org/onlinepubs/007904875/functions/atof.html – ArjunShankar

+0

2. '% d' es para enteros. Use '% f'. – ArjunShankar

Respuesta

21

le falta algún incluyen: #include <stdlib.h>, por lo GCC crea una declaración implícita de la atof y atod, lo que lleva a los valores de basura.

Y el especificador de formato para el doble es %f, no %d (es decir, para enteros).

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

int main() 
{ 
    char *test = "12.11"; 
    double temp = strtod(test,NULL); 
    float ftemp = atof(test); 
    printf("price: %f, %f",temp,ftemp); 
    return 0; 
} 
/* Output */ 
price: 12.110000, 12.110000 
+1

+1. Derecha. Este es el problema. [antes de la edición de PO, en realidad había tres problemas] – ArjunShankar

1

Código publicado por usted es correcto y debería haber funcionado. Pero verifique exactamente lo que tiene en el char*. Si el valor correcto es grande para ser representado, las funciones devolverán un HUGE_VAL positivo o negativo. Compruebe lo que tiene en el char* frente a los valores máximos que float y double pueden representar en su computadora.

Compruebe this page for strtod reference y this page for atof reference.

He intentado el ejemplo que proporcionaste tanto en Windows como en Linux y funcionó bien.

+1

De acuerdo con: http://pubs.opengroup.org/onlinepubs/007904875/functions/atof.html (que está alineado con el estándar C): "Si el valor no puede ser representado , el comportamiento no está definido ". – ArjunShankar

+0

Los valores son todos mucho más pequeños que el máximo que puede representar el tipo de variable, el valor más grande que tengo es 120.55. – Andrew

+0

@George: no use cplusplus.com. Está lleno de errores. Ni 'atof' ni' strtod' devuelven HUGE_VAL en caso de un desbordamiento. De acuerdo con [cppreference] (http://en.cppreference.com/w/c/string/byte/atof), el valor de retorno no está definido. –

0
printf("price: %d, %f",temp,ftemp); 
       ^^^ 

Esta es su problema. Dado que los argumentos son del tipo double y float, debe utilizar %f para ambos (ya que printf es una función variadic, ftemp se promocionará a double).

%d espera que el argumento correspondiente sea tipo int, no double.

Las funciones variables como printf realmente no conocen los tipos de argumentos en la lista de argumentos variables; tienes que contarlo con el especificador de conversión. Dado que usted indicó printf que se supone que el primer argumento es un int, printf tomará los siguientes sizeof (int) bytes de la lista de argumentos y lo interpretará como un valor entero; de ahí el primer número de basura.

Ahora, es casi seguro que sizeof (int) < sizeof (double), por lo que cuando printf da el siguiente sizeof (double) bytes de la lista de argumentos, probablemente empezando por el byte medio de temp, más que el primer byte de ftemp; de ahí el segundo número de basura.

Use %f para ambos.

Cuestiones relacionadas