C Teilstrings (Parameter) aus String lesen

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, 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
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, C#
Hmmm...
strtok wäre ein hilsfmittel
Addi
Hatte ich die ganze Zeit. Strtok scheint den String zu terminieren? Ich konnte auf jedenfall nicht mehrere Parameter einzeln lesen.
 

TommyB

Premium Benutzer
17 Mai 2010
2.001
74
48
35
127.0.0.1 ;)
Sprachen
Assembler, LunaAVR, VB.Net, Python, C#

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, C#

TommyB

Premium Benutzer
17 Mai 2010
2.001
74
48
35
127.0.0.1 ;)
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.
 

Mikro23

Mitglied
2 Jan 2017
295
22
18
Großraum Hannover
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.
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, C#
Naja, grade bei mehreren Parametern, wie soll C sonst das Ende von jedem Parameter erkennen? Normalerweise ja per 0x00 char.
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.

Und ja, strtok verändert den String. Wenn Du ihn noch unverändert brauchst, mußt Du also noch eine Kopie anlegen.
Kannst du mir sagen, was genau die Funktion am String verändert? Ist es evtl. wirklich der String Abschluss?
 

Mikro23

Mitglied
2 Jan 2017
295
22
18
Großraum Hannover
Sprachen
C, Assembler
Kannst du mir sagen, was genau die Funktion am String verändert?
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.
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, C#
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.
Okay und diese muss ich ja dann zwischenspeichern sonst gehen Sie verloren...
 

LotadaC

Sehr aktives Mitglied
22 Jan 2009
3.281
60
48
Hennigsdorf
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.
 
Zuletzt bearbeitet:

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, C#
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.
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?
 

Mikro23

Mitglied
2 Jan 2017
295
22
18
Großraum Hannover
Sprachen
C, Assembler
Du meinst die Zeiger oder wie?


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.
 

addi

Mitglied
2 Sep 2013
116
4
18
Hamminkeln
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
 

Janiiix3

Aktives Mitglied
28 Sep 2013
1.312
10
38
Hannover
Sprachen
C, C#
Hmmm....
Man könnte die parameter auch auf eine einheitliche länge vor der übertragung bringen, mit der anschliessend beim empfang gearbeitet wird
Addi
Ich möchte das ganze ja Variable halten. Das ich auf bestimmte Zeichen parse. Klappt ja auch soweit sehr gut.
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)