Integer nach ASCII umwandeln

Gast #275771
Lesenswert?
• ▲
▼
Ich versuche gerade von BASCOM auf C umzusteigen.
Habe eine kleines Unterprogramm geschrieben, welches eine Integerzahl
über den UART ausgibt:


void print_char (char c)
{
     while (!(UCSRA & (1<<UDRE))){}
         UDR = c;
}

void print_int (int wert)
{
  int temp;
  int i;


  for (i=0; wert!=0; i++)
  {
    temp = wert % 10;
    temp += 48;
    print_char(temp);
    wert /= 10;
  };
}

Das Funktioniert auch, allerdings werden die Stellen falsch herum (also
mit der kleinste Stelle zuerst ausgegebne).
Ich könnte zwar die einzelnen Stellen in ein ARRAY schreiben und dann,
falsch herum ausgeben.

Gibt es vielleicht eine eleganter Methode dafür?
Persönliche Seite #275778
Lesenswert?
• ▲
▼
Könntest auch Subtraktions-Methode nehmen:

Mit größter Zehnerpotenz anfangen, bei 3567 als Wert z.B. 1000:
1
int minuend = 1000;
2
char temp = 0;
3
while (zahl > minuend)
4
{
5
   zahl -= minuend;
6
   temp++;
7
}
8
temp += 48;

Das packste entweder in ne Schleife und jeden Schleifendurchgang
minuend / 10 oder du machst es halt 4-5x mit konstanten Minuenden.. ich
hoffe, das Ding heißt auch Minuend ;)
#275779
Lesenswert?
• ▲
▼
Entweder Du nimmst ein Array fuer die
Zwischenspeicherung oder du machst eine
rekursive Funktion:

void print_int_help (int wert)
{
  if( wert == 0 )
    return;

  int temp = wert % 10;
  print_int_help( wert / 10 );
  print_char( temp + '0' );
}

void print_int( int wert )
{
  if( wert == 0 )
    print_char( '0' );
  else
    print_int_help( wert );
}

Rekursive Funktionen werden in µC Programmierung nicht sehr
gerne gesehen, da sie alles am Stack abwickeln und der ist
meist eher knapp.
Gast #275780
Lesenswert?
• ▲
▼
Besser als "itoa" gefällt mir für solche Zwecke die Funktion
"sprintf", die genauso wie printf arbeitet, allerdings ihr Ergebnis
in eine anzugebenden (und ausreichend großen) String schreibt. Damit
kann man nicht nur die Zahl wandeln, sondern auch gleich noch was zu
deren Bedeutung schreiben (muss man aber nicht ;).

Gruß
Konrad
Gast #275783
Lesenswert?
• ▲
▼
Danke für eure Antworten.
Ich habe es jetzt doch so wie ich es am Anfang geschrieben habe
realisiert.
Speicher jetzt jede Stell im Array ab und gib es dann wieder Rückwerts
aus.
Ist am einfachsten, auch wenn es vielleicht eleganter geht.
Gast #275784
Lesenswert?
• ▲
▼
Hier noch der Code

void print_char (unsigned char c)
{
     while (!(UCSRA & (1<<UDRE)));
         UDR = c;
}

void print_uint (unsigned int wert)
{
  unsigned char ziffer[5], anz=0,x;
  do
  {
    ziffer[anz++] = wert % 10 + 48;
  }
  while (wert /= 10);
  for (x=anz; x!=0; x--) print_char(ziffer[x-1]);
  print_char (13); //Carriage return
  print_char (10); //line feed
}
#275785
Lesenswert?
• ▲
▼
Das einzige was ich Dir ans Herz legen moechte, ist:

Gewoehn Dir schnell wieder ab, Zeichen durch ihren ASCII
Code auszudruecken:

  wert % 10 + 48

ist (bei ASCII) absolut equivalent zu:

  wert % 10 + '0';

nur dass man im zweiten Fall besser sieht, was da passiert.
Du willst das Ergebnis der modulo Division so bearbeiten
dass ein integer von 0 das Zeichen '0' ergibt, 1 zum Zeichen
'1' wird. usw.

Im Originalcode ist das nicht so offensichtlich. Spaetestens
nach 2 Wochen raetselst Du herum: Warum 48, warum 48, warum 48?
Bis es Dir dann wieder wie Schuppen aus den Haaren faellt: Der
ASCII Code von '0' ist 48.

Selbiges fuer 13 und 10
13 ist '\r'   Carriage return
10 ist '\n'   line feed

Schreibst Du:

   print_char( '\r' );
   print_char( '\n' );

dann kannst Du Dir auch die Kommentare sparen. Jeder der C kann,
sieht im Code, und nicht im Kommentar, dass hier Carriage Return
und Line Feed ausgegeben wird. Code sollte immer selbstkommentierend
sein.

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.