Forum: Mikrocontroller und Digitale Elektronik Float in String umwandeln


von Andreas S. (schunki)


Lesenswert?

Hallo zusammen!

So kurz vorm WE hab ich nochmal ein kleines Problem bei dem ich nicht 
weiter komme. Vielleicht kann mir da noch jemand weiter helfen.

Ich habe eine Anwendung bei der Schaltvorgänge ausgewertet werden und 
ein prozentualer Wert für die richtigen Schaltvorgänge über die UART 
Schnittstelle des Atmega32 ausgegeben werden soll.

Um den Wert ausgeben zu können, muss ich ihn aber in einen String 
umwandeln. Ich habe es jetzt wie folgt versucht:

1
char buffer[32];
2
float Prozentwert;
3
int Schalt_gesamt;
4
int Schalt_falsch;
5
6
Prozentwert=((Schalt_gesamt-Schalt_falsch)/Schalt_gesamt)*100;
7
sprintf(buffer,"%3.3f",Prozentwert);

wenn ich jetzt die Variable buffer ausgebe, dann erhalte ich nur ein 
"?". Auch bekomm ich von AVR-Studio eine Warnung angezeigt, dass der 
Compiler bei "%f" eine Variable vom Typ double erwartet. Das verwirrt 
mich dazu dann noch mehr, weil meines Wissens nach doch %f für eine 
float-Variable verwendet wird und double %lf wäre, oder seh ich das 
falsch?

Ich sag schon mal Danke im voraus!


Gruß
Andreas

von H.Joachim S. (crazyhorse)


Lesenswert?

Unabhängig von der gleich startenden Diskussion, ob float nötig oder 
nicht:
Es gibt höchstwahrscheinlich Compilereinstellungen, welche 
(s)printf-Typen unterstützt werden.
Welchen Compiler benutzt du?

von Steel (Gast)


Lesenswert?

1
Prozentwert=((Schalt_gesamt-Schalt_falsch)/Schalt_gesamt)*100;

Ist schonmal falsch, da bekommst du einen Integer raus der dann nur noch 
zum Float gewandelt wird (ohne Nachkommastellen).
1
Prozentwert=(((float)(Schalt_gesamt-Schalt_falsch)*100.0/ (float)Schalt_gesamt);

So macht mans auf Nummer sicher.

von sprintf (Gast)


Lesenswert?

Steel schrieb:
> So macht mans auf Nummer sicher.

Wobei das Casten von einem Operanden reichen sollte. float/int = float 
genauso wie int/float = float.

von Klaus W. (mfgkw)


Lesenswert?

Andreas Schunkert schrieb:
> Das verwirrt
> mich dazu dann noch mehr, weil meines Wissens nach doch %f für eine
> float-Variable verwendet wird und double %lf wäre, oder seh ich das
> falsch?

Da ein Standard-konformer Compiler an jede Funktion kein float übergibt, 
sondern immer eine double stattdessen, ist %f für double, aber letztlich 
auch für float.

Bei scanf dagegen wird nicht der Wert übergeben, also auch nicht 
konvertiert, sondern die Adresse.
Deshalb muß man dort %f für float nehmen und %lf für double (bzw. float* 
und double* natürlich).

Falls du von AVR mit avr-gcc redest: da gibt es eh keinen Unterschied 
zwischen float und double.

von Karl H. (kbuchegg)


Lesenswert?

Und zum Fragezeichen

> Auch bekomm ich von AVR-Studio

Welches genau?

Fürs 4-er geht das so
FAQ

Im Punkt:
Aktivieren_der_Floating_Point_Version_von_sprintf_beim_WinAVR_mit_AVRStu 
dio


Bei den neueren AVR-Studien muss prinzipiell dasselbe gemacht werden, 
nur sind die entsprechenden Einstellungen an anderer Stelle zu machen. 
Vielleicht weiß jemand, wo genau.

von Andreas S. (schunki)


Lesenswert?

H.joachim Seifert schrieb:
> Welchen Compiler benutzt du?

den AVR/GNU C Compiler

Eingestellte Optionen:
-funsigned-char-funsigned-bitfields -O1 -fpack-struct -fshort-enums -g2 
-Wall-c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -mmcu=($DEVICE)

von amateur (Gast)


Lesenswert?

So weit mir bekannt lautet die "offizielle" Definition der Funktion:

int sprintf ( char * str, const char * format, ... );

Viele Compiler fressen deinen Aufruf, aber manche wollen explizit einen 
Zeiger auf den ersten Parameter.

von Karl H. (kbuchegg)


Lesenswert?

amateur schrieb:
> So weit mir bekannt lautet die "offizielle" Definition der Funktion:
>
> int sprintf ( char * str, const char * format, ... );
>
> Viele Compiler fressen deinen Aufruf

müssen sie auch.

>, aber manche wollen explizit einen
> Zeiger auf den ersten Parameter.

Sein erster Parameter IST ein Zeiger.
Arrays werden in C immer per Pointer auf das erste Element übergeben. 
Der Name eines Arrays degeneriert automatisch zu einem entsprechenden 
Pointer.

von Karl H. (kbuchegg)


Lesenswert?

Andreas Schunkert schrieb:
> H.joachim Seifert schrieb:
>> Welchen Compiler benutzt du?
>
> den AVR/GNU C Compiler
>
> Eingestellte Optionen:
> -funsigned-char-funsigned-bitfields -O1 -fpack-struct -fshort-enums -g2
> -Wall-c -std=gnu99 -MD -MP -MF "$(@:%.o=%.d)" -mmcu=($DEVICE)


Der Compiler hat ausnahmsweise damit nichts zu tun. Du musst eine andere 
Library linken. Das ganze ist also eine Linker-Einstellung.

Und ich hab gerade gesehen, ein freundlicher Zeitgenosse hat die FAQ 
auch für die neueren AVR-Studio Versionen aktualisiert.

von Andreas S. (schunki)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Welches genau?

Ich nutze AVR Studio 5.1

von Andreas S. (schunki)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Der Compiler hat ausnahmsweise damit nichts zu tun. Du musst eine andere
>
> Library linken. Das ganze ist also eine Linker-Einstellung.
>
>
>
> Und ich hab gerade gesehen, ein freundlicher Zeitgenosse hat die FAQ
>
> auch für die neueren AVR-Studio Versionen aktualisiert.

Ich hab die Einstellungen jetzt wie in der FAQ beschrieben geändert. 
Allerdings muckt er beim comopilen immer noch, dass er bei %f einen 
double und keinen float erwartet.

von Karl H. (kbuchegg)


Lesenswert?

Andreas Schunkert schrieb:

> Ich hab die Einstellungen jetzt wie in der FAQ beschrieben geändert.
> Allerdings muckt er beim comopilen immer noch, dass er bei %f einen
> double und keinen float erwartet.

Na, dann gib ihm einen
(Und eigentlich ist die Warnung meinem Verständnis nach nicht richtig. 
Bei variadischen Funktionen ist genau geregelt, wie die Übergabe zu 
erfolgen hat. float werden als double übergeben)


  sprintf(buffer,"%3.3f",(double)Prozentwert);

von Andreas S. (schunki)


Lesenswert?

Alles klar Karl Heinz, so funktionierts!

Vielen Dank und ein schönes Wochenende!


Gruß
Andreas

von Padex (Gast)


Lesenswert?

Man kann vielleicht einfacher die Funktion
   dtostrf(...)   'double to string formatted' verwenden.
Zu finden in der stdlib.h .
  Example:  dtostrf( foo,6.3,textbuffer);  //foo: auszugebende 
Variable(float).
Alles erklärt im avr-lib Reference Manual.
mfg Padex.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.