web-dev-qa-db-ja.com

char *をfloatまたはdoubleに変換する

ファイルから読み込んだ値があり、char *として保存されます。値は通貨番号、#。##、##。##、または###。##です。 char *を計算に使用できる数値に変換したいのですが、atofとstrtodを試してみましたが、それらは単にガベージ番号を与えてくれます。これを行う正しい方法は何ですか?なぜ私がそれを間違っているのですか?

これは基本的に私がやっていることであり、char *値だけがファイルから読み込まれます。 temp変数とftemp変数を出力するとき、それらは単なるゴミであり、巨大な負の数です。

別の編集:

私はまさにこれを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;

}

私の出力は価格です:3344336.000000、3344336.000000

編集:ここに私のコードがあります

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

私の入力ファイルは、次のような非常に単純な名前と値のペアです。

NAME|VALUE
NAME|VALUE
NAME|VALUE

値はドル金額です

解決済み:ありがとうございます。%fの代わりに%dを使用しており、正しいヘッダーが含まれていませんでした。

10
Andrew

Include:#include <stdlib.h>が欠落しているため、GCCはatofおよびatodの暗黙的な宣言を作成し、ガベージ値を導きます。

また、doubleの書式指定子は%fではなく%dです(整数の場合)。

#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
28
user703016

あなたが投稿したコードは正しく、機能しているはずです。ただし、char*の内容を正確に確認してください。正しい値が表現するには大きすぎる場合、関数は正または負のHUGE_VALを返します。 char*にあるものを、floatおよびdoubleがコンピューター上で表すことができる最大値に対して確認します。

strtod参照用のこのページ および atof参照用のこのページ を確認してください。

WindowsとLinuxの両方で提供された例を試してみましたが、うまくいきました。

1
George
_printf("price: %d, %f",temp,ftemp); 
              ^^^
_

これはあなたの問題です。引数はdoubleおよびfloat型であるため、両方に_%f_を使用する必要があります(printfは可変機能関数であるため、ftempdouble)に昇格されます。

_%d_は、対応する引数がintではなくdouble型であると想定しています。

printfのような可変引数関数は、変数引数リスト内の引数のタイプを実際には知りません。変換指定子でそれを伝える必要があります。最初の引数はprintfであるとintに伝えたので、printfは引数リストから次のsizeof (int)バイトを取り出し、整数値として解釈します。したがって、最初のガベージ番号。

現在、sizeof (int) <sizeof (double)であることがほぼ保証されているため、printfが引数リストから次のsizeof (double)バイトを取得するときは、おそらくtempの最初のバイトではなく、ftempの中間バイト。したがって、2番目のガベージ番号。

両方に_%f_を使用します。

0
John Bode