int aus String extrahieren.

Hallo @all,
ich brauche mal eure Programmiererfahrungen. Ich programmiere normalerweise nur unter Windows. Das Stringhandling ist unter Arduino echt "schwer":

Folgendes Beispiel:

// aus der Variable cZeile...
char cZeile[] = "GET //231=25,77 HTTP/1.1";

//Sollen folgende Werte extrahiert werden:
int iPosition = 231;
float fWert = 25.77;

Hat hier jemand ein Beispielcode, womit ich aus der obigen Zeile die Werte extrahieren kann und den Variablen zuweisen kann.

Vielleicht zum Hintergrund: Ich versuche eine Webschnittstelle zu programmieren, über die ich verschiedene Parameter meines Prorgammes anpassen kann. Diese Parameter speichere ich in einem i2c-eeprom und lese Sie wärend des Programmablaufes aus. Zum Beispiel die Wiederholfrequenz in meinem Programm in Sekunden. Ich möchte die Parameter wie folgt übergeben:
http:///231=25,77.
Die 231 ist die Startadresse im eeprom und die 25,77 ist der Wert, der ab dort geschrieben werden soll.

Vielen Dank im Voraus

mcGeorge:
Hallo @all,
// aus der Variable cZeile...
char cZeile[] = "GET //231=25,77 HTTP/1.1";

//Sollen folgende Werte extrahiert werden:
int iPosition = 231;
float fWert = 25.77;

Hat hier jemand ein Beispielcode, womit ich aus der obigen Zeile die Werte extrahieren kann und den Variablen zuweisen kann.

Ich poste einfach nochmal meine genialistische getIntFromString-Funktion, die ich mal zu dem Zweck gecodet habe, Integer-Zahlen aus einem String zu ziehen:

int getIntFromString (char *stringWithInt, byte num)
// input: pointer to a char array
// returns an integer number from the string (positive numbers only!)
// num=1, returns 1st number from the string
// num=2, returns 2nd number from the string, and so on
{
  char *tail; 
  while (num>0)
  {
    num--;
    // skip non-digits
    while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;
    tail=stringWithInt;
    // find digits
    while ((isdigit(*tail))&&(*tail!=0)) tail++;
    if (num>0) stringWithInt=tail; // new search string is the string after that number
  }  
  return(strtol(stringWithInt, &tail, 0));
}

Damit kannst Du aus Deinem String "GET //231=25,77 HTTP/1.1" mit fünf verschiedenen Aufrufen die Integer-Zahlen:
231 25 77 1 1
herausziehen.

Beispielaufruf:
i=getIntFromString (cZeile, 1);
würde die 231 zurückliefern.

Wenn Du Gleitkommazahlen mit Dezimalpunkt und/oder Dezimalkomma rausziehen möchtest, oder Zahlen die den Integer-Wertebereich überschreiten, müßtest Du die Funktion natürlich in geeigneter Weise umschreiben. Oder ggf. mich fragen.

Wobei Du Dir natürlich auch Deine float Zahl selbst aus zwei Integers (Vorkommawert, Nachkommawert) zusammenbasteln kannst, wenn es sichergestellt ist, dass die Zahl garantiert mit zwei Nachkommastellen angegeben ist.

Viel Spaß damit!

Vielen Dank jurs für deine Hilfe. Das ist es, was ich gesucht habe.

Genial!

@jurs

Wie kann man dein Code verändern, um auch negative Zahlen aus dem String zu berücksichtigen.
Aktuell wird das Vorzeichen ja ignoriert und nur der Zahlenwert an sich ausgegeben.

"genialistische Software" darf nur der Meister persönlich ändern, sonst verliert sie ihre Genialität :wink:
Tip: Bei isdigit() ist '-' natürlich keine Ziffer

StandardFunktionen ( atoi, atol , ... ) können auch negativ.
Die können nur nicht die n-te Zahl in einem String erkennen.

=) genau an diesem Punkt stehe ich jetzt und weiß derzeit nicht weiter

was passiert bei

while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;

-->

while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0) && (*stringWithInt != '-')) stringWithInt++;

???

Mein Vorschlag war aber eher, zu prüfen, ob diese Spezialfunktion wirklich das ist, was du brauchst.

perfekt, Vielen Dank!

Mit deiner Ergänzung funktioniert es!!

mnui:
Mit deiner Ergänzung funktioniert es!!

"GET //231=25,77 HTTP/1.1";

Ich glaube das ist nicht gültig...
Das Gleichheitszeichen!

Meine Empfehlung:
"GET /231 HTTP/1.1"; // lesen
"POST /231/25.77 HTTP/1.1"; // setzen

Das würde dem REST Prinzip entsprechen
Siehe: REST

Bei jurs Funktion kann man noch Flash sparen, wenn man atoi() statt strtol() verwendet

Da tail an strtol() zu übergeben ist nämlich nicht nötig. Der zweite Parameter ist dazu da dass man die Funktion ähnlich wie strtok_r() verwenden kann. Also gleichzeitig nach Tokens splitten und wandeln. Der Parameter zeigt dann auf das erste Zeichen nach der Zahl und kann so beim nächsten Funktions-Aufruf als Anfang verwendet wird (mit einer Addition um das Trennzeichen zu überspringen). Das ist auch der Grund weshalb da ein Zeiger auf einen Zeiger übergeben wird. Das soll ein Rückgabe-Wert sein.

Das hier reicht:

int getIntFromString (char *stringWithInt, int num)
{
  char *tail; 
  while (num>0)
  {
    num--;
    while ((!isdigit (*stringWithInt))&&(*stringWithInt!=0)) stringWithInt++;
    tail=stringWithInt;

    while ((isdigit(*tail))&&(*tail!=0)) tail++;
    if (num>0) stringWithInt=tail;
  }

  return atoi(stringWithInt);
}

strtol() ist dagegen eher sinnvoll, wenn man Hex oder Binärzahlen wandeln muss