-
        

Ergebnis 1 bis 4 von 4

Thema: String am AVR parsen und zerlegen

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    18.09.2005
    Ort
    Seewalchen
    Alter
    30
    Beiträge
    10

    String am AVR parsen und zerlegen

    Anzeige

    SMARTPHONES & TABLETS-bis zu 77% RABATT-Kostenlose Lieferung-Aktuell | Cool | Unentbehrlich
    Hallo,
    ich hab da mal eine Frage: Würde euch ein möglichst einfacher und schlanker Code für das parsen und zerlegen eines Strings den ich über USART empfange einfallen? In der libc gäbs sogar ein strsep bzw. ein strtok_r, aus diesen beiden werde ich aber nicht schlau. Dann hab ich mir eine eigene Funktion geschrieben, die aber relativ umständlich ist und am AVR viel Speicher verbraucht.
    Darum meine Frage an euch:
    Ich sende per USART einen String, z.B. set time 12:00:00 oder get time oder help. Dann möchte ich den String in Teilstrings zerlegen, die durch Leerzeichen getrennt sind, die Anzahl der Argumente variiert jedoch. z.B. bei set time 12:00:00 hätte ich dann gerne 3 strings zu set, time und 12:00:00 (die Zeit verarbeite ich dann mit sscanf weiter). Oder beim Kommando help sollte nur in einem String eben help drin stehen. Die Abfrage kann man danach einfach mit strcmp machen.
    Ich hoffe jemand von euch weiß eine vernünftige Methode, um den String zu zerlegen.

    Danke und mfg n0Br4iN3r
    Der Horizont vieler Menschen ist ein Kreis mit dem Radius Null - und das nennen sie dann ihren Standpunkt.
    Albert Einstein

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Im eigentlichen Sinn zerlegen würd ich das Ding gar nicht.

    Eher angemessen scheint mir so was: Zeiger auf die Anfänge/Längen der einzelnen Teilstrings besorgen. Dadurch vermeidest du das rumkopieren des Strings und dynamisches Allokierung.

    Etwa so:

    char* getSubstring (char *str, char *length, unsigned char arg_no);

    return-Wert ist der Zeiger auf den Anfang des Teilstrings, *length die Länge desselbigen und arg_no die Nummer des Teilstrings (hier mit 1 angefangen zu zählen, evtl ist 0 günstiger).

    Beispiel: str="set time 12:00:00"
    getSubstring (str, &len, 1) --> len=3, return = str
    getSubstring (str, &len, 2) --> len=4, return = str+4
    getSubstring (str, &len, 3) --> len=8, return = str+9
    getSubstring (str, &len, 4) --> len=-1, return = NULL

    Oder was Destriktives, wenn das nicht zu Problemen führt: Das ' ' nach set durch Stringende '\0' ersetzen. Aber erst nachdem du den Anfang des Folgestrings ab time irgendwo gemerkt hast (local static etwa). Womöglich machen die Tokenizer genau sowas.

    sscanf() zieht wahrscheinlich einiges aus der libc bzw libgcc hinter sich her. Evtl den ganzen float-Klumbatsch, den du gar nicht brauchst. sprintf() ist auch super übel. Was alles dazugelinkt wird aus irgendwelchen Bibliotheken siehst du am Mapfile, das du beim Linken am besten immer mitgenerieren lässt.
    Disclaimer: none. Sue me.

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    18.09.2005
    Ort
    Seewalchen
    Alter
    30
    Beiträge
    10
    Danke für die Antwort, werd ich gleich mal probieren.
    mfg
    Der Horizont vieler Menschen ist ein Kreis mit dem Radius Null - und das nennen sie dann ihren Standpunkt.
    Albert Einstein

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.801
    Wenn dein Zeit-String immer in dem Format ankommt, ist das umrechnen simpel. Daß das Format stimmt stellt dein 'Parser' sicher bzw der Sender.

    Beispiel:
    char *time;
    time = "12:34:56";

    uint8_t stunde, minute, sekunde;

    stunde = 10*(time[0]-'0') + (time[1]-'0');
    minute = 10*(time[3]-'0') + (time[4]-'0');
    sekunde= 10*(time[6]-'0') + (time[7]-'0');

    oder
    stunde = my_atoi2 (time);
    minute = my_atoi2 (time+3);
    ...
    // Wandelt 2-stelligen Dezimal-String nach unsigned char
    uint8_t my_atoi2 (char *str)
    {
    // ... evtl noch ein Test aufs Format
    return 10*(str[0]-'0') + (str[1]-'0');
    }


    Den Klotz xscanf() und xprintf() brauchst du eigentlich nicht. Zwar bequem, vom Speicher- (RAM+Flash) und Zeitverbrauch her aber höllisch. Zumindest für Hänflinge wie AVR.
    Disclaimer: none. Sue me.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •