2012-05-15 9 views
7

Ich habe einen Wert ich aus einer Datei eingelesen und wird als Char * gespeichert. Der Wert ist eine monetäre Nummer, #. ##, ##. ## oder ###. ##. Ich möchte das char * in eine Zahl umwandeln, die ich in Berechnungen verwenden kann, ich habe atof und strtod ausprobiert und sie geben mir nur Müllnummern. Was ist der richtige Weg dies zu tun, und warum mache ich es falsch?Konvertieren von char * in float oder double

Dies ist im Wesentlichen was ich tue, nur der char * Wert wird aus einer Datei eingelesen. Wenn ich die Variablen temp und ftemp ausdrucke, sind sie nur Müll, gigantische negative Zahlen.

Ein weiterer Edit:

Ich laufe genau in diese 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; 

}

und meine Ausgabe ist der Preis: 3344336,000000, 3344336,000000

Edit: Hier ist mein Code

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); 

meine Eingabedatei ist sehr einfach Name, Wert-Paare wie folgt aus:

NAME|VALUE 
NAME|VALUE 
NAME|VALUE 

mit dem Wert Dollar

sein

GELÖST beträgt: Danke euch allen, ich anstelle von% f mit% d und didn‘ t haben die richtigen Header enthalten.

+4

Das Problem muss woanders sein, der von Ihnen gepostete Code ist absolut gültig und funktioniert. Bitte zeigen Sie uns, wie Sie Ihre Datei lesen. –

+0

1. 'atof' gibt auch' double' zurück: http://pubs.opengroup.org/onlinepubs/007904875/functions/atof.html – ArjunShankar

+0

2. '% d' steht für Integer. Verwende '% f'. – ArjunShankar

Antwort

21

Sie vermissen ein gehören: #include <stdlib.h>, so GCC eine implizite Deklaration von atof und atod, was zu Müll Werte schafft.

Und der Format-Spezifizierer für Doppel ist %f, nicht %d (das ist für Integer).

#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. Recht. Das ist das Problem. [Vor den OP-Änderungen gab es eigentlich drei Probleme] – ArjunShankar

1

Code von Ihnen geschrieben ist korrekt und sollte funktioniert haben. Aber überprüfen Sie genau, was Sie in der char* haben. Wenn der richtige Wert zu groß ist, um dargestellt zu werden, geben die Funktionen eine positive oder negative HUGE_VAL zurück. Überprüfen Sie, was Sie in der char* gegen Höchstwerte haben, die float und double auf Ihrem Computer darstellen können.

Überprüfen Sie this page for strtod reference und this page for atof reference.

Ich habe versucht, das Beispiel, das Sie in Windows und Linux zur Verfügung gestellt und es hat gut funktioniert.

+1

nach: http://pubs.opengroup.org/onlinepubs/007904875/functions/atof.html (die mit dem C-Standard ausgerichtet ist) vergessen: "Wenn der Wert nicht dargestellt werden kann , das Verhalten ist nicht definiert. " – ArjunShankar

+0

Die Werte sind alle viel kleiner als die Max, die jeder Variablentyp darstellen kann, der größte Wert, den ich habe, ist 120,55. – Andrew

+0

@George: Verwenden Sie nicht cplusplus.com. Es ist voller Fehler. Weder 'atof' noch' strtod' geben im Falle eines Überlaufs HUGE_VAL zurück. Laut [cppreference] (http://en.cppreference.com/w/c/string/byte/atof) ist der Rückgabewert nicht definiert. –

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

Das ist Ihr Problem. Da die Argumente vom Typ double und float sind, sollten Sie %f für beide verwenden (da printf eine variable Funktion ist, wird ftemp zu double hochgestuft).

%d erwartet das entsprechende Argument vom Typ int, nicht double.

Variadische Funktionen wie printf kennen die Typen der Argumente in der Variablenargumentliste nicht wirklich; Sie müssen es mit dem Konvertierungsspezifizierer angeben. Da Sie printf gesagt haben, dass das erste Argument ein int sein soll, wird printf die nächsten sizeof (int) Bytes aus der Argumentliste übernehmen und als Ganzzahl interpretieren; daher die erste Müllnummer.

Jetzt ist es fast garantiert, dass sizeof (int) < sizeof (double), so dass, wenn printf das nächste sizeof (double) Bytes aus der Argumentliste nimmt, ist es wahrscheinlich mit dem mittleren Byte temp, anstatt dem ersten Byte ftemp beginnen; daher die zweite Müllnummer.

Verwenden Sie %f für beide.