mikrocontroller.net

Forum: PC-Programmierung int to string


Autor: Krikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

ich muss für eine kleines Projekt eine int Zahl in einen String 
umwandel, damit er über die Serielle Schnittstelle im terminal 
ausgegeben werden kann.

Habe auch hier ein Codebeispiel dafür gefunden:

http://www.mikrocontroller.net/articles/FAQ#itoa.28.29

Allerdings hat es bei mir einen kleinen Fehler.
Und zwar gibt er bei negativen Zahlen das Minuszeichen nicht vor sondern 
nach der Zahl aus.
Desweitern meckert der Compiler bei der Zeile "Buffer++" Hab diese 
einfach weggelassen oder durch "Buffer[i++]" ersetzt. Dann war die 
Fehlermeldung weg, aber das Minus halt anders. Ich weiß auch nciht ob es 
an dieser Zeile evt. liegt.

Hier einmal der Code:

har * Int2String(int zahl)
{


  int i = 0;
  int j;
  const int size = 20;
  char Buffer[size];
  char tmp;
  unsigned u;    // In u bearbeiten wir den Absolutbetrag von zahl.
  
    // ist die Zahl negativ?
    // ein - hinterlassen und die Zahl positiv machen
    if( zahl < 0 ) {
      Buffer[0] = '-';
      //Buffer++; 
      //Buffer[i++];
      //i=1;
    u = abs(zahl);  //Absolutbetrag wird errechnet
    }
    else { 
      u = zahl;
    }
    // die einzelnen Stellen der Zahl berechnen
    do {
      Buffer[i++] = '0' + u % 10;
      u /= 10;
    } while( u > 0 );
 
  //durch fortgesetzte Division durch 10. Die einzelnen Ziffern der Zahl stehen in umgekehrter Reihenfolge im String.
    // den String in sich spiegeln sodass danach die Zahlen im String in der korrekten Reihenfolge stehen. 
    for(j = 0; j < i / 2; ++j ) {
      tmp = Buffer[j];
      Buffer[j] = Buffer[i-j-1];
      Buffer[i-j-1] = tmp;
    }
    Buffer[i] = '\0';    //Zahl wird abgeschlossen
  //Buffer[i] = '\n';    //Zahl wird abgeschlossen

  return Buffer;
}  

Autor: Doc. E. L. Brown (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wäre auch noch mit sprinft möglich. Da wird das Vorzeichen nach 
Bedarf richtig gesetzt; Nachteil: sprintf frisst gewaltig Flash.

Autor: chester (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf() willst/darfst du nicht nehmen?

Autor: Doc. E. L. Brown (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf natürlich... nicht sprinft

Autor: Krikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
sprintf kann ich nicht verwenden.
Aber mir fällt gerade ein, ich könnte ja das Minuszeichen statt als 
erstes als letztes in den String schreiben.
Dann müsste es doch vorne sein?

Kann es leider auch nicht testen jetzt, da dies nur an der Uni möglich 
ist.

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Aber mir fällt gerade ein, ich könnte ja das Minuszeichen statt als
> erstes als letztes in den String schreiben.
> Dann müsste es doch vorne sein?

Da du den String von hinten nach vorne aufbaust: ja. Oder du schreibst 
es erst vor dem "Spiegeln" nach vorne...

> Kann es leider auch nicht testen jetzt, da dies nur an der Uni möglich
> ist.

Wenn du zu Hause keinen Rechner hast, wie postest du dann?

Autor: Krikus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ICh habe hier daheim nicht die passende ARM-Entwicklungsumgebung mit den 
Peripheriekomponenten.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
har * Int2String(int zahl)
{


  int i = 1;
  int j;
  const int size = 20;
  char Buffer[size];
  char tmp;
  unsigned u;    // In u bearbeiten wir den Absolutbetrag von zahl.
  
    // ist die Zahl negativ?
    // ein - hinterlassen und die Zahl positiv machen
    if( zahl < 0 ) {
      Buffer[0] = '-';
    }
    else Buffer[0] = ' ';
    u = abs(zahl);  //Absolutbetrag wird errechnet
    // die einzelnen Stellen der Zahl berechnen
    do {
      Buffer[i++] = '0' + u % 10;
      u /= 10;
    } while( u > 0 );
 
  //durch fortgesetzte Division durch 10. Die einzelnen Ziffern der Zahl stehen in umgekehrter Reihenfolge im String.
    // den String in sich spiegeln sodass danach die Zahlen im String in der korrekten Reihenfolge stehen. 
    for(j = 1; j < i / 2; j++ ) {
      tmp = Buffer[j];
      Buffer[j] = Buffer[i-j-1];
      Buffer[i-j-1] = tmp;
    }
    Buffer[i] = '\0';    //String wird abgeschlossen
  return Buffer;
}  

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Krikus schrieb:
> ICh habe hier daheim nicht die passende ARM-Entwicklungsumgebung mit den
> Peripheriekomponenten.

Einen C-Compiler gibt es fuer dein Betriebssytem bestimmt, kein Problem 
also, das zuhause zu ueben. Und ueben kann ich dir nur dringend 
empfehlen, dir werden bei der Mikrocontrollerentwickler noch weit 
groessere Probleme begegnen. Zu guter letzt der unvermeidliche Buchtipp:

http://www.amazon.de/Programmieren-C-ANSI-2-C-Refe...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Krikus schrieb:

> Habe auch hier ein Codebeispiel dafür gefunden:
>
> http://www.mikrocontroller.net/articles/FAQ#itoa.28.29
>
> Allerdings hat es bei mir einen kleinen Fehler.

Nicht nur einen.

Bei dir ist Buffer ein lokales Array. Ein Array ist aber kein Pointer. 
Daher kannst du darauf kein ++ anwenden.

Gut das könnte man beheben. Aber deine Version hat noch einen 
entscheidenden Fehler: Du gibts die Adresse einer lokalen Variablen 
zurück und das ist ein echtes NoNo. Lokale Variablen werden zerstört, 
sobald eine Funktion verlassen wird. Und damit gibts du die Adresse auf 
einen Speicherbereich zurück, der nicht mehr existiert, sobald der 
Aufrufer deiner Funktion die Adresse in die Finger kriegt. Alles 
mögliche kann passieren.

Stringverarbeitung in C ist nicht so simpel. Wenn eine Funktion einen 
String manipulieren oder erzeugen soll, dann ist die vernünftigste 
Methode immer noch die, dass der Aufrufer der Funktion den Speicher für 
den String zur Verfügung stellen muss. Er übergibt dann die Adresse des 
SPeichers an die Funktion und im Idealfall auch noch die Länge dieses 
Speicherbereichs, damit die Funktion sich gegen Out-of-Bounds Zugriffe 
schützen kann.

> Desweitern meckert der Compiler bei der Zeile "Buffer++"

Das hätte dich schon stutzig machen sollen. Wenn du eine Musterlösung 
übernimmst, veränderst und der Compiler meldet dir einen Error, den du 
nicht beheben kannst oder von dem du nicht verstehst warum das jetzt ein 
Error ist, dann ist die Wahrscheinlichkeit hoch, dass du etwas Schlimmes 
angestellt hast. In C ist oft jedes einzelne Detail wichtig.

> Und ueben kann ich dir nur dringend empfehlen, dir werden bei der
> Mikrocontrollerentwickler noch weit groessere Probleme begegnen.
> Zu guter letzt der unvermeidliche Buchtipp:
>
> http://www.amazon.de/Programmieren-C-ANSI-2-C-Refe...

Ein Tip, den du unbedingt beherzigen solltest.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer schrieb:
>
> char * Int2String(int zahl)
> {
  ...

>   char Buffer[size];
  ....
>   return Buffer;
> }
> 

Selbes Problem: return einer lokalen Variablen

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Selbes Problem: return einer lokalen Variablen

Dachte ich mir doch.
Ich hatte bloß keine Lust das auch noch zu ändern.
Dazu müsste man dann ja "nur" noch einen Pointer auf das Array in der 
aufrufenden Funktion mit übergeben...
Sowas steht wunderbar in der C-Bibel beschrieben...

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
STK500-Besitzer schrieb:
>>Selbes Problem: return einer lokalen Variablen
>
> Dachte ich mir doch.

Der Ordnung halber: Hab mich verschrieben. Das sollte eigentlich "return 
der Adresse einer lokalen Variablen" heissen.
Ist schon klar, dass ich dir das nicht erzählen brauche. Aber du bist ja 
nicht der Einzige der das liest :-)

> Ich hatte bloß keine Lust das auch noch zu ändern.
> Dazu müsste man dann ja "nur" noch einen Pointer auf das Array in der
> aufrufenden Funktion mit übergeben...

Womit wir dann wieder zurück bei der Version aus der FAQ sind und sich 
die Frage erhebt, warum der TO das geändert hat :-)

> Sowas steht wunderbar in der C-Bibel beschrieben...

Yep. Und noch 100-te andere Kleinigkeiten, weswegen sich ein Erwerb und 
durchackern derselben immer lohnt.


Was mich auch immer wieder verblüfft: Da wird Code in Form einer 
vollständigen Funktion übernommen und noch ehe man die veröffentlichte 
Version ausprobiert, wird schon wie wild abgeändert. Und dann ist das 
Geschrei groß, dass nichts funktioniert. Dabei wär alles so einfach: 
Erst mal die Funktion so belassen wie sie ist. Wenn sie nicht geht, den 
Aufruf studieren ob man da nicht ev. einen Fehler gemacht hat. Wenn man 
sicher ist, dass beim Aufruf alles so ist wie es sein sollte, beim Autor 
nachfragen ob ein Problem bekannt ist (und seinen Aufruf zeigen). 
Funktioniert die originale Version so wie sie sollte, dann und erst dann 
mit den Änderungen anfangen. Dabei erweist es sich dann als nützlich, 
wenn man das Testprogramm zum testen des originalen Codes noch hat. 
Läuft dies plötzlich nicht mehr, dann hat man eine Verschlimmbesserung 
gemacht und kann sich die letzten Veränderungen noch mal durch den Kopf 
gehen lassen und gezielt fragen, wenn einem nicht klar ist, was den das 
Problem ist.

Warum ist so ein methodisches Vorgehen blos so schwer?

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Warum ist so ein methodisches Vorgehen blos so schwer?

Wieso? Programmieren ist doch Pippifax. Das lernt man an einem 
Nachmittag, und sonst gibt es ja für alles irgendwo im Netz ein Tool...

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.