Forum: Mikrocontroller und Digitale Elektronik Benutzt ihr sprintf()? Gute Alternative?


von Wolfsente (Gast)


Lesenswert?

Moin,

Benutzt ihr sprintf aufm 8bit uC?

Wenn ja, nur für Hobby Projekte?
Wenn nein "nur" wegen dem Speicherverbrauch?
1
#include <avr/io.h>
2
#include <stdio.h>
3
4
int main(void)
5
{
6
  char buffer[40];
7
8
    while(1)
9
    {
10
       sprintf(buffer, "value of %f", 12.22);
11
    }
12
}

Der Code verbraucht schon aufm Atmega644 mit der printf_flt schon 3254 
bytes und sind 5%.

Ich stelle die Frage, weil ich Hobbybastler bin und die Funktion halt 
gerne verwende, weil die halt wirklich zur string Formatierung alles 
kann.
Aber wie sehen das Leute die wirklich Ahnung davon haben? :D

Möchte mich auch gerne verbessern und wollte auch gerne nach einer 
weniger speicher fressenden Funktion fragen die ebenfalls die Funktion 
bietet mit *%8.2f*
(Das halt immer 8 Zeichen reserveriert sind, nach der zweiten stelle 
nach komma stelle abgeschnitten wird  und rechtsbündig ist.)
Dieses %8.2f benutz ich halt im string am häufigsten.

Habt ihr sowelchen Sachen dann selber geschrieben oder gibts da iwo eine 
schon fertige abgespeckte lib iwo im www?
(Das automatische Runden der nachkommastelle wäre mir persönlich nicht 
wichtig.)

Gruß

von weinbauer (Gast)


Lesenswert?

in Swift für iOS schon

von Thomas W. (diddl)


Lesenswert?

Bei den großen Atmega spielen die 3K keine große Rolle.

Für die Kleinen gibt es stark abgemagerte Varianten.


Ja ich verwende es sehr gerne.
Weil ich fast immer UART oder Display habe.

Wenn es nicht geht, auf den Tiny zb., dann lass ich es halt weg.

von wedelos (Gast)


Lesenswert?

Ich benutze immer sprintf von Georges Menie (www.menie.org).
Sehr sehr schlank.

von Joerg W. (joergwolfram)


Lesenswert?

Ich benutze sprintf praktisch gar nicht (mehr). Stattdessen habe ich mir 
ein eigenes printf "gebastelt", bei dem die eigentliche Ausgaberoutine 
über einen Funktionspointer realisiert wird. Für das Schreiben in den 
Speicher gibt es dann eine eigene Subroutine, die dann z.B. auch auf 
Arraygrenzen achten kann.

von batman (Gast)


Lesenswert?

Klar, was soll der Geiz.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

wedelos schrieb:
> Ich benutze immer sprintf von Georges Menie (www.menie.org).

Genauer:
http://www.menie.org/georges/embedded/

Ist hier nur nicht hilfreich - kann kein float.

(Auf der Seite gibt es zwar einen Link auf eine Variante, die float 
können soll, der Link aber ist tot und auch via archive.org nicht zu 
beleben)

: Bearbeitet durch User
von J. F. (Firma: Père Lachaise) (rect)


Lesenswert?

Ich benutze nur snprintf :-)

von Wolfsente (Gast)


Lesenswert?

Hey Leute,

Vielen dank für eure Antworten!

Ich denke ich werde mir die Version von Georges Menie mal genauer 
angucken!

Meistens kann man mit einen bisschen selber umrechnen ja auch die Floats 
umgehen.

Werde mein nächstes Projekt dann mal damit probieren.

Vielen dank nochmal :)

von A. S. (Gast)


Lesenswert?

Es gibt 3 gute Gründe, (s(n))printf nicht zu nutzen:

1) Textbastelroutinen werden nicht gebraucht
2) Zu fragil für Deine Programmierdisziplin
3) passt nicht in den Speicher.

Selber frickeln sollte man nur bei Punkt 3), nicht schon im 
vorauseilenden Gehorsam.

von S. R. (svenska)


Lesenswert?

Achim S. schrieb:
> 1) Textbastelroutinen werden nicht gebraucht

Sind aber hilfreich, wenn man Display und/oder UART hat.

> 2) Zu fragil für Deine Programmierdisziplin

Sehe ich anders. Gesunden Menschenverstand in der Benutzung 
vorausgesetzt.

> 3) passt nicht in den Speicher.

Hängt von der Nutzung ab.

> Selber frickeln sollte man nur bei Punkt 3), nicht schon im
> vorauseilenden Gehorsam.

Wenn in der Entwicklung kein Grund auftaucht, der die Benutzung von 
printf in Frage stellt (Speichermangel, garantiert deterministisches 
Timing, Zertifizierung), kann man es gern benutzen. Den Flash-Verbrauch 
für printf bezahlt man auch nur einmal, dann ist sowieso alles da.

Ich greife erst dann zu Krücken, wenn die Beine nicht richtig 
funktionieren. Vorher sehe ich keinen Grund dazu.

Eine der ersten Funktionen, die ich auf einer neuen Plattform zum Laufen 
bringe, ist printf. Deren Existenz macht viele Dinge in der Entwicklung 
einfacher, auch wenn sie im Endprodukt nicht mehr verwendet wird.

: Bearbeitet durch User
von A. S. (Gast)


Lesenswert?

S. R. schrieb:

Vielen Dank, dass Du alle meine Punkte untermauerst. Wortwahl und 
Satzbau suggerieren aber das Gegenteil. Vertue ich mich da?

von Armin G. (Firma: Rentenvers. Bund (Frührentner)) (armin_g)


Lesenswert?

Naja, {s,sn}printf(...) ist schon schön bequem. Es gibt dennoch 
Alternativen. Das Konvertieren von Zahlen mit z.B. lota(...) im 
Zusammenspiel mit strncpy(...) etc.

 Das ist allerdings bei führendenden Nullen im Zahlenbuffer dann ein 
wenig Gefummel. Insgesamt jedoch, insbesondere für "preformated" Strings 
schnell und einigermaßen schlank. Vermutlich auch etwas kleiner als die 
sprintf(...) Derivate, da zumindest bei "preformatted" Ausgaben, viele 
der möglichen Optionen in sprintf(...) von vorne herein weg fallen.

 Nur elegant sieht das natürlich nicht unbedingt aus, darüber sollte man 
sich nicht hinwegtäuschen. sprintf(...) ist auf alle Fälle besser 
lesbar, auch wenn der Code dahinter entsprechend 'deutlich gewichtiger' 
ist.

 Aber kleiner und meist auch schneller geht natürlich immer! Einfach 
Zahlen in einen Buffer fester Größe hinein konvertieren, anschliessend 
in den "preformatted String" an der vorgesehenen Stelle einfügen und 
schon geht die Reise in Richtung UART & Co los.
 Der Gewinn besteht dabei selbstverständlich nicht in der expliziten 
Konvertierung einer Zahl 'bin >> Ascii', das macht sprintf(...) auch 
nicht anders, sondern vielmehr im Weglassen der Notwendigkeit für die 
Interpretation der Formatierungsvorschrift im sprintf(...). Das macht 
schon ein klein wenig was aus.

 Solange es jedoch passt, was Timing und Platz angeht, bleib schon 
allein wegen der Lesbarkeit bei den sprintf(...) Derivaten. So sieht man 
wenigstens immer gleich was erzielt werden sollte, ohne Ellen lange 
Kommentare in den Source schreiben zu müssen.


Mit besten Grüßen aus Berin!


p.s. Für ATMEL gibt es angeblich eine zum Thema passende dtostrf(...) in 
der avr-libc. Ich persönlich kenne die jedoch nicht, da ich mehr mit 
PIC8/PIC16/PIC32 unterwegs bin.

Quelle: 
http://www.atmel.com/webdoc/AVRLibcReferenceManual/group__avr__stdlib_1ga060c998e77fb5fc0d3168b3ce8771d42.html

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Wolfsente schrieb:
> Meistens kann man mit einen bisschen selber umrechnen ja auch die Floats
> umgehen.

Dann musst du aber auch aus der avr-libc nicht gleich die teuerste
Version mit Gleitkommaunterstützung benutzen.  Die ist ja aus gutem
Grunde nicht der Default, sondern die musst du explizit mit
einbinden.

von Peter D. (peda)


Lesenswert?

Wolfsente schrieb:
> Benutzt ihr sprintf aufm 8bit uC?

Ja natürlich.


Wolfsente schrieb:
> Der Code verbraucht schon aufm Atmega644 mit der printf_flt schon 3254
> bytes und sind 5%.

Das wird ja nur einmal benötigt.

von S. R. (svenska)


Lesenswert?

Achim S. schrieb:
> Vielen Dank, dass Du alle meine Punkte untermauerst. Wortwahl und
> Satzbau suggerieren aber das Gegenteil. Vertue ich mich da?

Meiner Meinung nach ist von der Verwendung von printf in wenigen 
(relativ klar definierten) Situationen abzuraten, d.h. in der Mehrheit 
aller Fälle ist es angezeigt. Und selbst in diesen Situationen sehe ich 
printf noch sinnvolles als Debugwerkzeug an.

Deinen Text lese ich umgekehrt, d.h. "per default nicht verwenden", und 
dem widerspreche ich.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

S. R. schrieb:
> Deinen Text lese ich umgekehrt, d.h. "per default nicht verwenden"

Ich denke, dass er keineswegs umgekehrt gemeint war.  Er hat drei
Gründe genannt, wann man es nicht verwenden sollte – wenn man
keinen der drei hat, sollte man es also verwenden …

von S. R. (svenska)


Lesenswert?

Stimmt, kann man auch so lesen. Dann stimmen wir überein.

von M. K. (sylaina)


Lesenswert?

Hm, ich bin noch nie in die Verlegenheit gekommen, sprintf() auf nem AVR 
zu brauchen...ich glaub ich mach was falsch.
Aber ich wills mal so sagen: Wenn man den Speicher hat und einem 
sprintf() genügt, warum sollte man es dann nicht nutzen?

von Matthias Q. (zaphod_beeblebrox)


Lesenswert?

Von freiem Speicher kann mich mir kein Bier kaufen... Wenn die 
Rahmenbedingungen es erlauben ja. Basteln mit %100 und so kann man immer 
noch, wenn es sein muss.

von W.S. (Gast)


Lesenswert?

M. K. schrieb:
> Hm, ich bin noch nie in die Verlegenheit gekommen, sprintf() auf nem AVR
> zu brauchen...ich glaub ich mach was falsch.

;-) ... Nö, du machst wohl nix falsch.

Ich selber benutze printf und Konsorten garnicht. Ich brauch's nicht, 
denn ich hab Ausgabekonvertierungen zur Genüge in meinem Portfolio.

Aber der TO ist schon lange gegangen.

W.S.

von A. S. (Gast)


Lesenswert?

W.S. schrieb:
> Ich brauch's nicht, denn ich hab Ausgabekonvertierungen
> zur Genüge in meinem Portfolio.

magst Du uns kurz darlegen, was Deine Gründe und was Deine 
Konvertierungen sind?

von Peter D. (peda)


Lesenswert?

Vielfach ist die Ablehnung von printf/float einfach nur historisch 
begründet.
Die AVRs waren ja lange Zeit recht spartanisch ausgerüstet. Z.B. vom 
viel eingesetzen AT90S4433 hat es sehr lange gedauert bis zum 
ATmega328P.
Und auch am AT89C52 mußte man lange Zeit externen Flash ranpappen, wenn 
die 8kB nicht mehr reichten.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Achim S. schrieb:
> was Deine Konvertierungen sind?

Sowas braucht W.S. einfach nicht.  Echte Männer™ lassen sich die
Bytes binär aufs Terminal ausgeben und wissen danach, welche Zahlen
sich dahinter verstecken. :-)

von holger (Gast)


Lesenswert?

>Echte Männer™ lassen sich die
>Bytes binär aufs Terminal ausgeben

Echte Männer benutzen auch keinen Assembler.
Die tippen die HEX-Datei direkt ein. Inklusive Checksumme.

von A. S. (Gast)


Lesenswert?

Ich habe viel Zeit damit vertrödelt, ungenutzten Speicher zu schonen...

[Kennt die Brillen-Werbung noch einer??]

Sohn (~40): >> wenn Du Dein Leben noch einmal leben könntest: würdest Du 
alles nochmal genauso machen?

Vater (70+): >> Nicht ganz ... Ich würde von Anfang an printf nutzen

von Dirk (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Genauer:
> http://www.menie.org/georges/embedded/
>
> (Auf der Seite gibt es zwar einen Link auf eine Variante, die float
> können soll, der Link aber ist tot und auch via archive.org nicht zu
> beleben)

Die float Variante von Derell Licht findet sich jetzt unter:
http://derelllicht.com/snippets.html

von Sebastian S. (amateur)


Lesenswert?

sprintf ist sprichwörtlich eine eierlegende Wollmilchsau!

Mich wundert’s deshalb auch nicht, dass das Teil so ein Trumm ist. 
Allerdings gehöre ich auch nicht zur 
Clicky-Bunty-schnell-einfüge-Fraktion.

Also sollte die Hauptfrage sein: Brauch ich das alles?

Die meisten werden ein paar, schon sehr oft verwendete, Routinen in 
ihrem Funktionspool haben, weil die Problematik bekannt ist. Vor allem 
die älteren unter uns, die früher noch die Bytes zählen mussten.

Georges Menie kannte ich noch nicht, wenn ich aber höre, dass der keine 
Fließkommazahlen mag, kann ich mir gut vorstellen, wieso die Bibliothek 
so schlank ist.

Die etwas schlankeren Alternativen snprintf, atoi und Konsorten sollte 
man als bekannt voraussetzen. Selbst atof spart ein paar Bytes.

von Karl M. (Gast)


Lesenswert?

Hallo,

ich nutze:
ELM - Embedded String Functions
http://elm-chan.org/fsw/strf/xprintf.html

von Einer K. (Gast)


Lesenswert?

Jörg W. schrieb:
> Echte Männer™
Nutzen Arduino!

Und da sind sprintf() und seine Brüder erreichbar.
Und wenns dann auch noch float Unterstützung braucht, ist das mit einem 
kleinen Dreh auch drin. Kostet allerdings über 1k Flash extra.

Und nein!
Wenns das Gedöns fertig gibt, dann schreibe ich es nicht selber, wenn es 
nicht unbedingt sein muss.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Sebastian S. schrieb:
> Selbst atof spart ein paar Bytes.

Gemessen, oder einfach nur behauptet?

Ich wette, dass 50 % der Leute, die printf & Co. „aus Prinzip, weil
sie zu fett sind“ nicht nehmen, am Ende mehr Platz mit ihren
selbstgestrickten Konvertierungen vertüddeln, als sie sich mit
einem gut optimierten printf() eingehandelt hätten. ;-)

von M. K. (sylaina)


Lesenswert?

holger schrieb:
> Echte Männer benutzen auch keinen Assembler.
> Die tippen die HEX-Datei direkt ein. Inklusive Checksumme.

Wer macht das denn nicht?

Achim S. schrieb:
> Ich habe viel Zeit damit vertrödelt, ungenutzten Speicher zu schonen...
>
> [Kennt die Brillen-Werbung noch einer??]
>
> Sohn (~40): >> wenn Du Dein Leben noch einmal leben könntest: würdest Du
> alles nochmal genauso machen?
>
> Vater (70+): >> Nicht ganz ... Ich würde von Anfang an printf nutzen

Naja, ich finde ihr übertreibt aber auch ein wenig. Man macht sich 
einmal ein paar Gedanken bzgl. Float und Strings und das kann man 
ständig nutzen. Da sollte ein printf() auch nicht unbedingt das 
Hindernis sein.

von A. S. (Gast)


Lesenswert?

Karl M. schrieb:
> ich nutze:
> ELM - Embedded String Functions
> http://elm-chan.org/fsw/strf/xprintf.html

sieht für mich aus, wie ein sprintf ohne float. Gibt es weitere 
Unterschiede und was sind die Vorteile zu den typischen floatlosen 
sprintf-Varianten der Compiler?

von W.S. (Gast)


Lesenswert?

Jörg W. schrieb:
> Ich wette, dass 50 % der Leute, die printf & Co. „aus Prinzip, weil
> sie zu fett sind“ nicht nehmen, am Ende mehr Platz mit ihren
> selbstgestrickten Konvertierungen vertüddeln, als sie sich mit
> einem gut optimierten printf() eingehandelt hätten. ;-)

Nun, in diesem Punkte stimme ich dir zu.
Die von dir angesprochenen Leute können nicht mal ne primitive 
Integer-Ausgabe schreiben, ohne ein mittleres Chaos anzurichten.

Aber eben diese Leute nehmen sowas wie printf nich deshalb, weil es 
ihnen zu fett wäre, sondern weil sie es weder besser wissen noch besser 
können. Das ist der Punkt. Unfähigkeit eben.

Ein kleinerer Teil könnte es wohl besser, hält sich aber für zu 
"großartig", um es auch tatsächlich besser zu machen. Die Denke von 
denen lautet "ich scher mich nicht drum, benutze nur Vorgefertigtes, 
weil ich mich ja sonst selber in solche Niederungen begeben müßte, 
igitt! - und wenn der µC zu klein oder zu lahm dafür ist, dann ist das 
ein Problem vom Cheffe und nicht meines - für sowas bin ich mir zu 
schade." Ist weit verbreitet. Such mal auf deimen PC in allen 
ausführbaren Dateien nach Formatstings "%d" oder "%H". In manchen 
Anwendungen findet man einige hundert derartiger Strings.

Nun, ich selber benutze printf und Konsorten eigentlich garnicht. Wozu 
auch? Bei Delphi auf dem PC hat man sowas nicht nötig und auf nem µC 
löse ich Textausgaben bereits beim Schreiben auf. Siehe conv.c bei der 
Lernbetty. Immerhin ist jeder wenigstens einigermaßen sinnvoll 
geschriebene Ausgabekonverter besser als jede printf Implementierung, 
weil der String-Interpreter nicht erforderlich ist.

W.S.

von HiHo (Gast)


Lesenswert?

Wolfsente schrieb:
> sprintf(buffer, "value of %f", 12.22);

Ich benutze immer printf ("...");

Warum nimmst Du nicht einfach das?

von Joachim B. (jar)


Lesenswert?

nach Bedarf, wenn der Platz knapp wird eigene Routinen oder größeren µC.

von S. R. (svenska)


Lesenswert?

W.S. schrieb:
> Aber eben diese Leute nehmen sowas wie printf nich deshalb, weil es
> ihnen zu fett wäre, sondern weil sie es weder besser wissen noch besser
> können. Das ist der Punkt. Unfähigkeit eben.

Ich weiß, was gut für mich ist und ich habe die Alternative auch schon 
selbst geschrieben und benutzt. Dennoch nutze ich printf, wenn nix 
dagegen spricht. Im Gegenteil, ich habe irgendwo eine minimale 
Implementation fürs Debugging herumliegen.

> Such mal auf deimen PC in allen ausführbaren Dateien nach Formatstings
> "%d" oder "%H". In manchen Anwendungen findet man einige hundert
> derartiger Strings.

Wenn du an einer Stelle printf benutzt, dann kannst du es auch gleich 
überall benutzen. Zudem ist es die Standard-Schnittstelle von C 
(natürlich nicht von Delphi) und für PCs durchaus geeignet.

Mir ist ein einfacher Formatstring (der sogar vom Compiler gegengeprüft 
wird, zumindest bei gcc/clang) lieber, als ein Haufen Funktionsaufrufe, 
die das zusammenpopeln. Selbst Einwickeln hält den Gestank nicht ab.

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.