C Teilstrings (Parameter) aus String lesen

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 7. August 2018.

  1. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Nabend,

    möchte z.B aus dem eingehenden Sring " -Parameter:1,2,3,4,5; " die einzelnen Parameter lesen und ausgeben.
    Die einzelnen Parameter sollten nach Möglichkeit nicht zwischengespeichert werden.



    CodeBox C und C++
    char     *cmdGetPara   ( cmd_t *cmd , char *input , uint8_t num )
    {
     char   *delimiter  = NULL;
     char   *cmdEndPtr = NULL;
     const char  *rawPtr  = NULL;
     uint8_t x;
      
     for ( x = 0 ; x < cmd->tabLen ; x++ )
     {
      rawPtr = cmdSearch( input , ( char * ) cmd->table[x].instruction );
      if ( rawPtr != NULL )
      {
       break;
      }
     }
      
     if ( rawPtr == NULL )
     {
      return NULL;
     }
     
     cmd->raw->paraNumb = cmdCntPara( ( char * ) rawPtr );
     
     cmdEndPtr = strchr( rawPtr , ';' );
     if ( cmdEndPtr == NULL )
     {
      return  NULL;
     }
     delimiter = strchr( rawPtr , ':' ) + 1;
     if ( ( delimiter - 1 ) == NULL )
     {
      return  NULL;
     }
     uint8_t pos;
     pos = strcspn( delimiter , "," );
     
     return delimiter;
    }
    


    Wie stelle ich das am besten an?
    Ich gebe würde der Funktion gerne übergeben, welchen Parameter er mir jetzt zurück geben soll.
    Das ganze ohne Trennzeichen ( ',' ) und ohne String ende Zeichen ( ';* ).

    Als Rückgabeparameter hätte ich gerne den Anfang des Parameters. Hier auch wieder ohne Trennzeichen.

    Jemand eine Idee wie man das am besten löst?

    Hier hatte wohl auch noch keiner eine Idee
    https://www.mikrocontroller.net/topic/456761#new
     
    #1 Janiiix3, 7. August 2018
    Zuletzt bearbeitet: 7. August 2018
  2. addi

    addi Mitglied

    Registriert seit:
    2. September 2013
    Beiträge:
    92
    Zustimmungen:
    3
    Punkte für Erfolge:
    8
    Sprachen:
    BascomAVR, C, Assembler
    Hmmm...
    strtok wäre ein hilsfmittel
    Addi
     
  3. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Hatte ich die ganze Zeit. Strtok scheint den String zu terminieren? Ich konnte auf jedenfall nicht mehrere Parameter einzeln lesen.
     
  4. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.684
    Zustimmungen:
    55
    Punkte für Erfolge:
    48
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
  5. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
  6. TommyB

    TommyB Premium Benutzer

    Registriert seit:
    17. Mai 2010
    Beiträge:
    1.684
    Zustimmungen:
    55
    Punkte für Erfolge:
    48
    Sprachen:
    Assembler, LunaAVR, VB.Net, Python, C#
    Naja, grade bei mehreren Parametern, wie soll C sonst das Ende von jedem Parameter erkennen? Normalerweise ja per 0x00 char.
    Könntest höchstens alle Parameter zusammen als ein Pointer übergeben und in jeder Routine selbst behandeln, falls der RAM eng wird.
    Vielleicht kann man tricksen und "," in 0x00 umwandeln, dann fehlt wiederrum aber der Anfang des jeweiligen Parameters.

    Prinzipiell was du vorhast ist performancetechnisch besser, aber hochgradig Fehleranfällig.
    Und da es scheinbar eh eine Art genereller Parser werden soll, möglicherweise auch noch von anderen verwendet, ist es sinnvoller alle möglichen späteren Fehlerquellen auszuschließen. Meine Meinung.
     
  7. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    strtok erwartet beim ersten Aufruf eine Adresse.

    Ein nicht gespeicherter String hat keine Adresse...

    Und ja, strtok verändert den String. Wenn Du ihn noch unverändert brauchst, mußt Du also noch eine Kopie anlegen.
     
  8. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Ich habe es jetzt bisschen anders gelöst.


    CodeBox C und C++
    char     *cmdGetPara   ( cmd_t *cmd , char *out , char *in , uint8_t num ) 
    {
     const char  *rawPtr  = NULL;
     uint8_t x;
     
     for ( x = 0 ; x < cmd->tabLen ; x++ )
     {
      rawPtr = cmdSearch( in , ( char * ) cmd->table[x].instruction );
      if ( rawPtr != NULL )
      {
       break;
      }
     }
     
     if ( rawPtr == NULL )
     {
      return NULL;
     }
      
     char *streamPtr = in;
     
     streamPtr = strchr( in , CMD_RAW_DATA_BEGINN[0] ) + 1;
     
     uint8_t i;
     for ( i = 0 ; i < num ; i++ )
     {
      streamPtr = strchr( streamPtr , CMD_RAW_PARA_DELIMITER[0] ) + 1;
     }
      
     char *outPtr = out;
     while( *streamPtr != '\0' && *streamPtr != CMD_RAW_PARA_DELIMITER[0] && *streamPtr != CMD_DATA_END[0] )
     {
      if ( *( streamPtr )  == CMD_CRC_BEGINN[0] )
      {
       return NULL;
      }
      *outPtr++ = *streamPtr++;
     }
     
     return out;
    }
    


    Werde jetzt doch die einzelnen Parameter die haben möchte selber in einen externen Puffer zwischen lagern. Das klappt bis jetzt erstmal soweit wie es soll. Natürlich kann ich da noch einiges optimieren.

    Kannst du mir sagen, was genau die Funktion am String verändert? Ist es evtl. wirklich der String Abschluss?
     
  9. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Wenn ich mich recht erinnere, werden alle delimiter durch 0x00 ersetzt. Das ist auch der übliche Stringabschluß in C, d.h. also nach mehrfachem strtok-Aufruf hast Du alle Teilstrings als Einzelstrings, jeweils mit Startadresse und mit 0x00 beendet.
     
  10. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Okay und diese muss ich ja dann zwischenspeichern sonst gehen Sie verloren...
     
  11. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.925
    Zustimmungen:
    44
    Punkte für Erfolge:
    48
    Sprachen:
    BascomAVR, Assembler
    Wenn es immer noch um den Kommandointerpreter aus dem anderen Thread geht, würde ich(!) das ganze bereits während des zeichenweisen Empfanges mit einer State-Machine angehen. Gepuffert werden dann maximal die einzelnen Elemente einmal, und sobald erkannt wird der entsprechende State geschaltet. Dann kann der Puffer das nächste Elemet aufnehmen. Statt des ganzen Stringes speicherst Du nur noch die Elemente, sofern sie nicht sofort ausgeführt werden können/sollen.
    Dazu muß natürlich erstmal die Syntax deiner Kommando-Sprache definiert sein.
     
    #11 LotadaC, 8. August 2018 um 18:10 Uhr
    Zuletzt bearbeitet: 8. August 2018 um 18:29 Uhr
  12. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler
    Wenn Du die Adressen meinst, stimmt es.
    Die Einzelstrings bleiben da stehen, wo sie standen, im Originalstring oder der Kopie, je nachdem welche Du bearbeitet hast.
     
  13. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Du meinst die Zeiger oder wie?
    Der String ist ja in einem Vector bzw. Array gespeichert.
    Wenn ich jetzt mit stringtok die Adresse des ersten Teilstringes ermittel, zeigt dieser ja auch nur auf den Vector wo dieser gespeichert ist. Oder sehe ich das jetzt falsch?
     
  14. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    250
    Zustimmungen:
    19
    Punkte für Erfolge:
    18
    Sprachen:
    C, Assembler


    CodeBox C und C++
    ptr = strtok(string, delimiter);
    ptr, string und delimiter sind Zeiger.
    Zeiger sind Namen für Speicherplätze, die Adressen enthalten.
    Die Adressen wiederum verweisen (zeigen) auf Speicherstellen, die Daten enthalten.

    Nach dem ersten Aufruf von strtok steht in ptr die selbe Adresse, wie in string (und der erste delimiter wurde durch 0x00 ersetzt).
    Die Adresse, die in ptr steht, mußt Du Dir merken, weil sie beim zweiten Aufruf überschrieben wird.
    Nach dem zweiten Aufruf steht in ptr die Adresse des Zeichens, das nach dem eingefügten 0x00 im String steht (und der zweite delimiter wurde durch 0x00 ersetzt).
    Etc.
     
  15. addi

    addi Mitglied

    Registriert seit:
    2. September 2013
    Beiträge:
    92
    Zustimmungen:
    3
    Punkte für Erfolge:
    8
    Sprachen:
    BascomAVR, C, Assembler
    Hmmm....
    Man könnte die parameter auch auf eine einheitliche länge vor der übertragung bringen, mit der anschliessend beim empfang gearbeitet wird
    Addi
     
  16. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.230
    Zustimmungen:
    7
    Punkte für Erfolge:
    38
    Sprachen:
    C
    Ich möchte das ganze ja Variable halten. Das ich auf bestimmte Zeichen parse. Klappt ja auch soweit sehr gut.
     
  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren und die Seite optimal für dich anzupassen. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden