www.mikrocontroller.net

Forum: Compiler & IDEs int Zahlen aus String ziehen


Autor: Philipp Schmidt (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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...

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Werner B. (Gast)
Datum:

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

Autor: Werner B. (Gast)
Datum:

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

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"zahl = atoi(text + i);"

funktioniert übrigens auch ...

Autor: Philipp Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.
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.

Autor: Fritz Ganter (fritzg)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die formatierung macht hinterher sowiso indent ;-)

Autor: Philipp Schmidt (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: Rolf (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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.