Forum: PC-Programmierung int to string


von Krikus (Gast)


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:
1
har * Int2String(int zahl)
2
{
3
4
5
  int i = 0;
6
  int j;
7
  const int size = 20;
8
  char Buffer[size];
9
  char tmp;
10
  unsigned u;    // In u bearbeiten wir den Absolutbetrag von zahl.
11
  
12
    // ist die Zahl negativ?
13
    // ein - hinterlassen und die Zahl positiv machen
14
    if( zahl < 0 ) {
15
      Buffer[0] = '-';
16
      //Buffer++; 
17
      //Buffer[i++];
18
      //i=1;
19
    u = abs(zahl);  //Absolutbetrag wird errechnet
20
    }
21
    else { 
22
      u = zahl;
23
    }
24
    // die einzelnen Stellen der Zahl berechnen
25
    do {
26
      Buffer[i++] = '0' + u % 10;
27
      u /= 10;
28
    } while( u > 0 );
29
 
30
  //durch fortgesetzte Division durch 10. Die einzelnen Ziffern der Zahl stehen in umgekehrter Reihenfolge im String.
31
    // den String in sich spiegeln sodass danach die Zahlen im String in der korrekten Reihenfolge stehen. 
32
    for(j = 0; j < i / 2; ++j ) {
33
      tmp = Buffer[j];
34
      Buffer[j] = Buffer[i-j-1];
35
      Buffer[i-j-1] = tmp;
36
    }
37
    Buffer[i] = '\0';    //Zahl wird abgeschlossen
38
  //Buffer[i] = '\n';    //Zahl wird abgeschlossen
39
40
  return Buffer;
41
}

von Doc. E. L. Brown (Gast)


Lesenswert?

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

von chester (Gast)


Lesenswert?

sprintf() willst/darfst du nicht nehmen?

von Doc. E. L. Brown (Gast)


Lesenswert?

sprintf natürlich... nicht sprinft

von Krikus (Gast)


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.

von der mechatroniker (Gast)


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?

von Krikus (Gast)


Lesenswert?

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

von STK500-Besitzer (Gast)


Lesenswert?

1
har * Int2String(int zahl)
2
{
3
4
5
  int i = 1;
6
  int j;
7
  const int size = 20;
8
  char Buffer[size];
9
  char tmp;
10
  unsigned u;    // In u bearbeiten wir den Absolutbetrag von zahl.
11
  
12
    // ist die Zahl negativ?
13
    // ein - hinterlassen und die Zahl positiv machen
14
    if( zahl < 0 ) {
15
      Buffer[0] = '-';
16
    }
17
    else Buffer[0] = ' ';
18
    u = abs(zahl);  //Absolutbetrag wird errechnet
19
    // die einzelnen Stellen der Zahl berechnen
20
    do {
21
      Buffer[i++] = '0' + u % 10;
22
      u /= 10;
23
    } while( u > 0 );
24
 
25
  //durch fortgesetzte Division durch 10. Die einzelnen Ziffern der Zahl stehen in umgekehrter Reihenfolge im String.
26
    // den String in sich spiegeln sodass danach die Zahlen im String in der korrekten Reihenfolge stehen. 
27
    for(j = 1; j < i / 2; j++ ) {
28
      tmp = Buffer[j];
29
      Buffer[j] = Buffer[i-j-1];
30
      Buffer[i-j-1] = tmp;
31
    }
32
    Buffer[i] = '\0';    //String wird abgeschlossen
33
  return Buffer;
34
}

von P. S. (Gast)


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-Reference/dp/3446154973/ref=sr_1_2?ie=UTF8&s=books&qid=1243690688&sr=8-2

von Karl H. (kbuchegg)


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.

von Karl H. (kbuchegg)


Lesenswert?

STK500-Besitzer schrieb:
>
1
> char * Int2String(int zahl)
2
> {
3
  ...
4
5
>   char Buffer[size];
6
  ....
7
>   return Buffer;
8
> }
9
>

Selbes Problem: return einer lokalen Variablen

von STK500-Besitzer (Gast)


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...

von Karl H. (kbuchegg)


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?

von STK500-Besitzer (Gast)


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...

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.