Forum: Compiler & IDEs int Zahlen aus String ziehen


von Philipp Schmidt (Gast)


Angehängte Dateien:

Lesenswert?

Wieder einmal Array to int Problem:
Ich verwenden Atmega8 und möchte die Zeichenkette die an die
UART-Schnittstelle gesendet wird auswertn und dabei die letzten beiden
Ziffern als Integer Werte weiterverarbeiten.

Im Klartext:
An der UART des Atmels kommt zB an:
Baumhaus 25

-> Baumhaus wird abgeschnitten (bereits realisiert siehe Listing)
-> 2
-> 5
-> sollen nun die Integer Zahl y=25 ergeben

Wie stelle ich das an? Habe mein Glück schon mit atoi() versucht, werde
aber darus nicht schlau...

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Mal ein Beispiel:

  char Text[] = "Baumhaus 25";
  int Wert;

  Wert = atoi(Text + strlen("Baumhaus "));

Oder:

  char Buffer[] = "Baumhaus 25";
  char *Pointer;
  int Wert;

  Pointer = Buffer + strlen("Baumhaus ");

  Wert = atoi(Pointer);


Hilft das?

von Werner B. (Gast)


Lesenswert?

Oder falls der Text vor der Zahl nicht bekannt ist
1
int i, zahl;
2
for(i=0;text[i]!='\0'&&!isdigit(text[i]);i++) ;
3
zahl = atoi(text[i]);

von Werner B. (Gast)


Lesenswert?

äää sorry, natürlich "zahl = atoi(&text[i]);"

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

"zahl = atoi(text + i);"

funktioniert übrigens auch ...

von Philipp Schmidt (Gast)


Lesenswert?

Danke für die schnellen Antworten, bin allerdings nicht weitergekommen.
Würde den Wert gerne über

uart_send(Wert);

als Test ausgeben aber da tut sich gar nichts..

Verstehe einfach nicht woran das liegt!?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Was macht denn "uart_send"?
Das ist eine Funktion, die einzelne Zeichen an die serielle
Schnittstelle ausgibt.

"Wert" hat in Deinem Beispiel den Wert 25, das ist ein Steuerzeichen,
das ein Terminalprogramm in der Regel gar nicht darstellen kann.

Damit Dein Wert in einer für Dich verständlichen Form angezeigt wird,
müsstest Du ihn in eine Zeichenfolge "2" und "5" umwandeln und
diese Zeichen nacheinander mit "uart_send" ausgeben.

von Werner B. (Gast)


Lesenswert?

@Rufus,

das mit dem "zahl = atoi(text + i);" ist mir persönlich nicht
aussagekräftig genug. Dass es sich bei text um einen zeiger handelt
wird verschleiert. Der weg über &text[i] ist zwar mehr tipparbeit aber
"sprechender". Der compiler genereriert in beiden fällen den gleichen
code, also ist es im grunde genommen egal.
Dass ich relativ grossen wert auf "sprechenden" sourcecode lege
ersiehtst Du auch schon aus "text[i]!='\0'"; Es wird explizit mit
dem NULL - character verglichen und nicht einfach mit 0.
(-:  Werner

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


Lesenswert?

> Der weg über &text[i] ist zwar mehr tipparbeit aber
> "sprechender".

Geschmackssache.  Ich finde, dass für jeden, der das Kapitel über
Zeiger und Felder im K&R verstanden hat, text + i auf Grund der
geringeren Häufung kryptischer Zeichen die bessere Übersichtlichkeit
bietet.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hmm.

Ich programmiere schon so lange in C, daß ich Dinge, die mir so
selbstverständlich wie das Atmen erscheinen, nicht explizit
hinschreibe.
Dazu gehört ein Vergleich mit 0, '\0' oder NULL (die letzten beiden
sind übrigens etwas unterschiedliches).

Dafür strukturiere ich Quelltext durch an bestimmten Stellen eingefügte
Leerzeichen.
1
for (i = 0; text[i] && !isdigit(text[i]); i++);

So sähe das bei mir aus.


Um auf Deine eingängliche Kritik einzugehen:
Die Variable "text" würde, wenn sie denn in einem vergleichbaren
Kontext verwendet wird, von mir nicht "text", sondern
höchstwahrscheinlich "pText" genannt werden.

All' das aber sind philosophische Betrachtungen, es gibt unendliche
Streitereien zwischen verschiedenen Fraktionen von C-Programmierern
über die Quelltextformatierung; entscheidend ist, daß man für sich
selbst ein konsistentes System verwendet.
Hält man das konsistent durch, besteht mit einiger Übung die
realistische Chance, daß man auch mehrere Jahre alte Quelltexte
problemlos warten kann.

von Fritz G. (fritzg)


Lesenswert?

Wenn statt Baumhaus was anderes stehen kann, es aber ein Wort ist geht
auch:

char tmp[20];
int wert;

sscanf(text,"%s %d",tmp,&wert);

Zahlt sich aber nur aus, wenn scanf schon dazugelinkt wurde, sonst
frisst dir das so 1-2 kByte.

von Werner B. (Gast)


Lesenswert?

Die formatierung macht hinterher sowiso indent ;-)

von Philipp Schmidt (Gast)


Lesenswert?

Ok,
vielen Dank hat funktioniert!

Was mir noch absoulut unklar ist wie ich nun aus dem erhaltenen Wert
(dezimal) einen Wert in Hexadezimal erhalte (mit dem Hex-Wert möchte
ich dann einzelne Ports meines Atmels ansteuern). Geht das ohne
weiteres überhaupt oder muss man den "normalen" Weg der DEZ -> HEX
Umrechnung gehen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Der von atoi (oder sscanf) gelieferte Wert ist ein binärer Wert und kann
einfach so in ein Portregister geschrieben werden (sofern auf den
möglichen Wertebereich geachtet wird).

Die Konvertierung von dezimal in binär hat bereits atoi (bzw. sscanf)
durchgeführt.

von Rolf (Gast)


Lesenswert?

Zum Einscannen einer Ganzzahl sollte man möglichst nie atoi nehmen, weil
das keine Hexadezimalzahlen einliest.
Stattdessen sollte man immer strtol nehmen:

int i=strtol(argv[1], (char **)NULL, 0);

wobei argv[1] nur ein Beispiel für eine einzuscannende Zahl, in Form
eines nullterminierten Strings, ist.
Damit werden auch Oktalzahlen richtig eingelesen.

von Rolf Magnus (Gast)


Lesenswert?

> Zum Einscannen einer Ganzzahl sollte man möglichst nie atoi
> nehmen, weil das keine Hexadezimalzahlen einliest.

Ein viel wichtiger Grund ist, daß atoi einen schwerwiegenden
Designfehler hat, nämlich, daß man nicht erkennen kann, ob die
Konvertierung erfoglreich war (sprich: ob der String überhaupt eine
Zahl enthalten hat).

von Rolf (Gast)


Lesenswert?

Ja, eigentlich hätte atoi auch deshalb zumindest aus den Lehrbüchern
verschwinden sollen, aber Traditionen halten sich lange, wie man auch
an gets und anderen sieht.

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.