itoa mit zwei Dezimalstellen

Gast #2355224
Lesenswert?

Guten Morgen zusammen,

ich verwende ein HD44780 kompatibles Display an einem Atmega32.
Auf dem Display möchte ich die Uhrzeit anzeigen.
Als LCD-Bibliothek verwende ich die von Peter Fleury. Die funktioniert 
auch einwandfrei.

Mein Problem liegt eher bei der itoa Funktion, die AVR-GCC mitbringt. 
Solange die Stellen für Sekunden, Minuten oder Stunden einstellig sind, 
ist der ausgegebene String auch nur einstellig. Das ist natürlich 
unschön, wenn die Einer zuerst auf der Zehnerstelle stehen und erst bei 
Zahlen >9 auf Ihre eigentliche Stelle rücken.

Gibt es da eine elegante Möglichkeit, dem String eine führende 0 zu 
verpassen?
#2355254
Lesenswert?

Für eine enizelne Zahl würde ich eventuell auch itoa nehmen.
Wenn Flash-Platz kein Problem ist, würde ich aber gleich sprintf nehmen. 
Ist einfach komfortabler, weil man da die komplette Uhrzeit in einem 
Aufwasch formatieren lassen kann

  sprintf( buffer, "%02d:%02d:%02", stunden, minuten, sekunden );
  lcd_puts( buffer );

fertig.
Ein bischen Overhead ist mir dann der Komfort schon wert.
Gast #2355263
Lesenswert?

Klaus Wachtler schrieb:
> nicht unbedingt, den Doppelpunkt kann man ja einmal ausgeben und muß ihn
> nicht laufend aktualisieren.
> Insofern braucht man ihn nicht im String mit der Zahl.

Ob das positionieren des LCD-Cursors auf das jeweilige Zahlenfeld 
schneller ist, als immer den ganzen String auszugeben ... ?

MfG Klaus
#2355281
Lesenswert?

Hallo,

Man kann auch ein eigenes itoa benutzen.
Puffer muss 8 Zeichen lang sein.

Temp = stunden / 10;
Puffer[0] = Temp + '0';
Temp = Stunden - 10*Temp;//== stunden % 10
Puffer[1] = Temp + '0';
Puffer[2] = ':';  // Braucht nur einmal sein
Temp = minuten / 10;
Puffer[3] = Temp + '0';
Temp = minuten - 10*Temp;
Puffer[4] = Temp + '0';
Puffer[5] = ':';   // Braucht nur einmal sein
Temp = sekunden - 10*Temp;
Puffer[6] = Temp + '0';
Puffer[7] = 0;  // Braucht nur einmal sein

Und es gibt sicher noch tausende Varianten ;-)
Gast #2355323
Lesenswert?

Vielen Dank schonmal für die zahlreichen Antworten!
Meine Frage zielte ja schon eher in die Richtung, das hauseigene itoa zu 
verwenden, ab.
Vom Komfort her gefällt mir die Version mit sprintf dann doch schon am 
besten. Ich werde das mal austesten und dann berichten. (wird aber vor 
morgen nicht passieren, da ich jetzt weg muß...)
#2355381
Lesenswert?

MarioG schrieb:
> Vielen Dank schonmal für die zahlreichen Antworten!
> Meine Frage zielte ja schon eher in die Richtung, das hauseigene itoa zu
> verwenden, ab.

Wenn du sowieso eine hauseigene itoa Lösung hast, ist es am besten sich 
mit dem Systemprogrammierer kurzzuschliessen und ihn um eine 
Spezialversion zu bitten.

Denn für itoa bedeutet die Forderung keine führenden 0-en zu erzeugen 
Aufwand.

Damit bist du in der paradoxen Situation, dass itoa erst Aufwand 
betreibt um die führenden 0-en wegzukriegen und du hinten nach Aufwand 
betreibst um diese wieder reinzukriegen.
#2355475
Lesenswert?

rené s. schrieb:
> hatte gestern auch ganau das gleiche problem.
> habs evtl. etwas pfuschig gelöst:
> nimm für jede ziffer eine eigene variable:
> stunden 1er, stunden 10er, minuten 1er, minuten 10er, usw...
> wie gesagt vlt nicht die schönste lösung aber funzt!

keine so gute Lösung.
Du verringerst zwar den Aufwand bei der Ausgabe, dafür hast du aber mehr 
Aufwand beim Weiterzählen der Uhrzeit. Wenn dann zb noch Weckzeiten ins 
Spiel kommen, schlägt das ganze dann ins Gegenteil um. Für ein bischen 
einfachere Programmierung in der Ausgabe treibst du eine Menge 
Mehraufwand in der internen Behandlung von Zeiten.
#2355697
Lesenswert?

Hubert G. schrieb:
> Man kann auch mit strlen abfragen ob eine oder zwei Stellen vorhanden
> sind und die 0 dann wieder einfügen.
Leider Nein, denn die führende '0' müßte davor eingefügt werden.
Wer weiß was dort steht und somit überschreibt.

Die Methode von Klaus Wachtler funktioniert deshalb, weil er einen 
Puffer = array of char vorgibt.
Die sicherste, insbesondere bei falschen Werten, ist sprintf.
Gast #2359515
Lesenswert?

Das schöne Wetter hat mich davon abgehalten, das zu testen. Ich werd das 
aber schon noch nachholen.

Karl Heinz Buchegger schrieb:
> Wenn du sowieso eine hauseigene itoa Lösung hast, ist es am besten sich
> mit dem Systemprogrammierer kurzzuschliessen und ihn um eine
> Spezialversion zu bitten.

Da hab ich mich wohl mißverständlich ausgedrückt. Ich meinte mit 
'hauseigen' die, die avr-gcc mitbringt.
Gast #2365200
Lesenswert?

Da bei sprintf der Compiler Probleme bereitete, hab ich jetzt einfach 
den Vorschlag von Klaus Wachtler übernommen.
Für meine Anwendung völlig ausreichend und funktioniert auch wunderbar.
Vielen Dank für die Hilfe nochmal!
Gast #2369212
Lesenswert?

Karl Heinz Buchegger schrieb:
> Wahrscheinlich fehlt einfach nur der richtige Include für sprintf
>
> #include <stdio.h>

Das hatte ich schon beachtet.

Udo Schmitt schrieb:
> Ich bezweifle daß der Compiler das Problem ist.
> Bei uns heisst es: "Das Problem sitzt meistens vor der Tastatur"
> Und zu 99% stimmt das, sogar dort wo mit Software Geld verdient wird :-)

Das Problem sitzt insofern vor der Tastatur, als daß ich nicht bereit 
war, ewig Zeit zu investieren, um den Fehler zu suchen und zu beheben.
Ich sollte vielleicht erwähnen, daß ich nicht unter Windows mit 
AVRStudio arbeite, sondern unter Linux mit Codeblocks. Das Problem 
scheint in der in meinem ubuntu release (10.10 bzw maverick merkaat) 
verwendeten avr-libc zu liegen.
Die Fehlermeldung lautete wie folgt:
"/usr/lib/avr/lib/libc.a(vfprintf_std.o): In function `vfprintf':
/build/buildd/avr-libc-1.6.8/avr/lib/avr2/../../../libc/stdio/vfprintf.c 
:338:  undefined reference to `__mulhi3'
/build/buildd/avr-libc-1.6.8/avr/lib/avr2/../../../libc/stdio/vfprintf.c 
:341:  undefined reference to `__mulhi3'"

An einer Problemlösung wäre ich natürlich schon interessiert!

Horst Hahn schrieb:
> Hallo,
>
> ach wie schade.
> Ich hatte gerade
> Temp = stunden / 10;
> durch
> Temp = ( int (stunden) * 26) >> 8 ;
> ersetzt, was auch nur bis knapp über 60 funktioniert und ohne Divsion
> auskommt.

Temp = ( int (stunden) * 26) / 256 ;
würde das der Compiler nicht genauso interpretieren? Wäre auf jeden fall 
einfacher zu lesen ;)
Gast #2369622
Lesenswert?

char puffer[4];

 lcd_clear();

 itoa((int) stunden+100, puffer, 10);
 lcd_string(&puffer[1]);

 lcd_string(" : ");

 itoa((int) minuten+100, puffer, 10);
 lcd_string(&puffer[1]);

 lcd_string(" : ");

 itoa((int) sekunden+100, puffer, 10);
 lcd_string(&puffer[1]);

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren