31

floatみんな、関数で変数を使用できるかどうか知りたいですsprintf()

同様に、次のように記述します。

sprintf(str,"adc_read = %d \n",adc_read);

adc_read整数変数で、文字列を格納します

"adc_read = 1023 \n"

str(と仮定して adc_read = 1023

整数の代わりに float 変数を使用するにはどうすればよいですか?

4

13 に答える 13

58

printf()組み込みプラットフォームを使用しているため、 -style 関数のすべての機能を利用できない可能性は十分にあります。

フロートがまったくあると仮定すると(まだ埋め込まれたものに必ずしも与え​​られているわけではありません)、次のようなものでエミュレートできます。

char str[100];
float adc_read = 678.0123;

char *tmpSign = (adc_read < 0) ? "-" : "";
float tmpVal = (adc_read < 0) ? -adc_read : adc_read;

int tmpInt1 = tmpVal;                  // Get the integer (678).
float tmpFrac = tmpVal - tmpInt1;      // Get fraction (0.0123).
int tmpInt2 = trunc(tmpFrac * 10000);  // Turn into integer (123).

// Print as parts, note that you need 0-padding for fractional bit.

sprintf (str, "adc_read = %s%d.%04d\n", tmpSign, tmpInt1, tmpInt2);

整数のサイズに基づいて、小数点以下の文字数を制限する必要があります。たとえば、16 ビットの符号付き整数では、4 桁に制限されます (9,999 は、表現できる最大の 10 のべき乗 -1 です)。

ただし、必要な精度が得られるまで、小数部分をさらに処理し、毎回 4 桁ずつシフトする (そして整数部分を使用/減算する) ことによって、これを処理する方法があります。


アップデート:

avr-gccあなたが他の答えの1つへの応答で使用していたとあなたが言及した最後のポイント。ここ%fであなたのprintf()ステートメントで使用するために何をする必要があるかを説明しているように見える次の Web ページを見つけました。

私が最初に思ったように、浮動小数点をサポートするには追加の作業が必要です。これは、組み込みのものが浮動小数点をほとんど必要としないためです (少なくとも、私がこれまでに行ったことはありません)。これには、メイクファイルに追加のパラメーターを設定し、追加のライブラリとリンクすることが含まれます。

ただし、一般的な出力形式を処理する必要があるため、コード サイズがかなり大きくなる可能性があります。浮動小数点数の出力を小数点以下 4 桁以下に制限できる場合は、コードを関数に変換し、それを使用することをお勧めします。スペースを大幅に削減できる可能性があります。

リンクが消えた場合に備えて、gcc コマンドに"-Wl,-u,vfprintf -lprintf_flt -lm". これは次のように変換されます。

  • vfprintf を最初は未定義にします (リンカーが解決する必要があるように)。
  • printf()検索する浮動小数点ライブラリを指定します。
  • 検索する数学ライブラリを指定します。
于 2009-05-25T09:13:56.967 に答える
6

このようなものは本当に簡単ではありません:

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

char str[10];
float adc_read = 678.0123;

dtostrf( adc_read, 3, 4, temp );
sprintf(str,"adc_read = %10s \n", temp);
printf(temp);
于 2012-05-24T21:56:50.007 に答える
2

はい、もちろん、フロートには特別なことは何もありません。float やその他のデータ型に対して printf() で使用するのと同じように、フォーマット文字列を使用できます。

編集 私はこのサンプルコードを試しました:

float x = 0.61;
char buf[10];
sprintf(buf, "Test=%.2f", x);
printf(buf);

出力は: Test=0.61

于 2009-05-25T08:53:32.297 に答える
2

はい、できます。ただし、リンク先の C ライブラリに依存するため、その結果に注意する必要があります。

組み込みアプリケーション用にプログラミングしているので、浮動小数点サポートは多くの組み込みアーキテクチャ用にエミュレートされていることに注意してください。この浮動小数点サポートでコンパイルすると、実行可能ファイルのサイズが大幅に増加します。

于 2009-05-25T09:00:53.187 に答える
2

%f修飾子を使用します。

sprintf (str, "adc_read = %f\n", adc_read);

例えば:

#include <stdio.h>

int main (void) 
{
    float x = 2.5;
    char y[200];

    sprintf(y, "x = %f\n", x);
    printf(y);
    return 0;
}

これをもたらします:

x = 2.500000

于 2009-05-25T08:51:31.007 に答える
1

sprintf (または varargs を使用するその他の関数) が自動的に何かをキャストするとは思わないでください。コンパイラは、書式文字列を読み取ったり、キャストしたりすることはありません。実行時に、sprintf にはスタック上に何があるかを判断するためのメタ情報がありません。バイトをポップして、フォーマット文字列で指定されたものとして解釈するだけです。sprintf(myvar, "%0", 0); すぐにセグメンテーション違反。

つまり: フォーマット文字列とその他の引数は一致する必要があります!

于 2009-05-25T09:01:33.763 に答える
0

プラットフォームのsprintfのドキュメントを参照してください。通常は%fまたは%eです。明確な答えが見つかる唯一の場所はドキュメントです...ドキュメント化されていない場合は、サプライヤに連絡するだけです。

それはどのプラットフォームですか?誰かがすでにドキュメントがどこにあるか知っているかもしれません...:)

于 2009-05-25T10:35:16.367 に答える
0

これをしないでください。C/C++ の整数は常に切り捨てられるため、floor 関数を使用する必要はありません。

char str[100]; 
int d1 = value;

使用する方が良い

int d1 = (int)(floor(value));

次に、整数部分の切り上げは行われません (68.9999999999999999 は 69.00 になります..)。68.1 の代わりに 68.09999847 を使用することを避けるのは困難です。どの浮動小数点形式も精度が限られています。

于 2009-12-31T04:06:02.803 に答える
0

はいといいえ。他のいくつかの返信が言ったことにもかかわらず、C コンパイラsprintf()、次のように、および他のすべての可変個引数関数の変換を実行する必要があります。

  • char=>int
  • short=>int
  • float=>double

(および上記の整数型の符号付き/符号なしバリアント)

これは、sprintf()(およびその他のprint()-family 関数) がそれなしでは使用できないためです。(もちろん、そのままではかなり使い物になりません。)

しかし、他の変換を想定することはできず、コードは未定義の動作をします - 読んでください: クラッシュ! -あなたがそれをするなら。

于 2009-05-25T09:15:58.960 に答える
0

%gはこれを行うことができます:

#include <stdio.h>
int main() {
  float w = 234.567;
  char x[__SIZEOF_FLOAT__];
  sprintf(x, "%g", w);
  puts(x);
}
于 2016-01-12T04:49:50.127 に答える
0

上記の paxdiablo に似ています。より広いアプリに挿入されたこのコードは、STM32 NUCLEO-F446RE で正常に動作します。

#include <stdio.h>
#include <math.h>
#include <string.h>
void IntegFract(char *pcIntegStr, char *pcFractStr, double dbValue, int iPrecis);

main()
{
   char acIntegStr[9], acFractStr[9], char counter_buff[30];
   double seconds_passed = 123.0567;
   IntegFract(acIntegStr, acFractStr, seconds_passed, 3);
   sprintf(counter_buff, "Time: %s.%s Sec", acIntegStr, acFractStr);
}

void IntegFract(char *pcIntegStr, char *pcFractStr, double dbValue, int 
iPrecis)
{
    int iIntegValue = dbValue;
    int iFractValue = (dbValue - iIntegValue) * pow(10, iPrecis);
    itoa(iIntegValue, pcIntegStr, 10);
    itoa(iFractValue, pcFractStr, 10);
    size_t length = strlen(pcFractStr);
    char acTemp[9] = "";
    while (length < iPrecis)
    {
        strcat(acTemp, "0");
        length++;
    }
    strcat(acTemp, pcFractStr);
    strcpy(pcFractStr, acTemp);
}

counter_buff には 123.056 が含まれます。

于 2020-01-01T15:37:27.737 に答える
-2

はい、%f を使用します

于 2009-05-25T08:51:47.057 に答える