mikrocontroller.net

Forum: Compiler & IDEs String Bearbeitung


Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich habe ein String so "AA BBB CCC DD" definiert. Und jetzt will jedes 
Block auf verscheienen stelle von anderem Variabel speichern.ZB AA auf 
String_Variabel[0], BBB=String_Variabel[1] usw. Wie mache ich es am 
besten.
Danke.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht der String immer gleich aus? Soll heissen: Ist der Aufbau
immer gleich? Hat also AA immer 2 Stellen und BBB immer 3?

Wenn ja, dann könnte strncpy() dein Freund sein.

Wenn nein, dann musst du den aufwändigeren Weg gehen und zuerst
mal die Leerzeichen im String suchen (zb. mit strchr())
und dann die Teilstrings mit zb. strncpy() extrahieren.
Eine andere Möglichkeit wäre auch strtok() in Verbindung mit
strcpy() oder strncpy().

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nein es kann unterschiedlihe Länge haben.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank wrote:
> nein es kann unterschiedlihe Länge haben.

Dann würde ich über strtok() und strcpy() (bzw. strncpy()) gehen.
Ist die einfachere Variante, wenn es den Fall nicht gibt, dass
ein Stringbestandteil auch fehlen kann.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
es klappt immer nicht, ich habe die Meldung:error: too few arguments to 
function 'strchr'.Hier ist die Funktion, in der das String bearbeitet 
wird.

void dekrypt_data()
{
char *ptrStr;
char buffer[20];
int i=0;
char dekryptString[30]="SEND AA BB CCC";

  lendekryptString=strlen(dekryptString);

    if(ptrStr=((char*)(strchr(dekryptString)," "))==NULL);
    {     strcpy(buffer[i]=ptrStr);
                     i++;
                           ptrStr+=1;
                }
         else
        ptrStr+=1;
}
Danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank wrote:
> hallo,
> es klappt immer nicht, ich habe die Meldung:error: too few arguments to
> function 'strchr'.Hier ist die Funktion, in der das String bearbeitet
> wird.

Das 2.te Argument für strchr ist kein String sondern ein char
(eigentlich ein int), der für das Zeichen steht, das gesucht werden
soll.

>    if(ptrStr=((char*)(strchr(dekryptString)," "))==NULL);
Solange du dir nicht sicher bist, was du tust, solltest du
auf solche Ausdrucksmonster verzichten.
In der einen Zeile sind alleine 3 schwere Fehler enthalten.

>     {     strcpy(buffer[i]=ptrStr);
strcpy will 2 Argumente.

#include <stdio.h>
#include <string.h>

char Command[20];
char CmdArg1[20];
char CmdArg2[20];
char CmdArg3[20];

unsigned char dekrypt_data( char* Data )
{
  int Len = strlen( Data );
  char* pPtr;

  Command[0] = '\0';
  CmdArg1[0] = '\0';
  CmdArg2[0] = '\0';
  CmdArg3[0] = '\0';

  // Extrahiere das Commando, falls es einens gibt
  pPtr = strtok( Data, " " );
  if( pPtr == NULL )
    return 0;

  strncpy( Command, pPtr, sizeof( Command ) );

  // Extrahiere das Erste Argument, falls es eines gibt
  pPtr = strtok( NULL, " " );
  if( pPtr == NULL )
    return 1;

  strncpy( CmdArg1, pPtr, sizeof( Command ) );

  // Extrahiere das Zweite Argument, falls es eines gibt
  pPtr = strtok( NULL, " " );
  if( pPtr == NULL )
    return 2;

  strncpy( CmdArg2, pPtr, sizeof( Command ) );

  // Extrahiere das Dritte Argument, falls es eines gibt
  pPtr = strtok( NULL, " " );
  if( pPtr == NULL )
    return 3;

  strncpy( CmdArg3, pPtr, sizeof( Command ) );

  return 4;
}


int main()
{
  char Line[] = "SEND AA BBB CC";
  unsigned char NrArgs;

  NrArgs = dekrypt_data( Line );

  printf( "Nr of recognized Strings: %d\n", NrArgs );
  if( NrArgs > 0 )
    printf( "Command: %s\n", Command );
  if( NrArgs > 1 )
    printf( "Argument1: %s\n", CmdArg1 );
  if( NrArgs > 2 )
    printf( "Argument1: %s\n", CmdArg2 );
  if( NrArgs > 3 )
    printf( "Argument1: %s\n", CmdArg3 );
}

Falls es ein Problem darstellt, dass der Originalstring in
dekrypt_data durch die strtok zerstört wird, müsste man zunächst
eine Kopie davon anlegen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habs grade gemerkt.
Die sizeof bei den strncpy gehören natürlich an das jeweilige
Zielarray angepasst.
Ist ein Copy&Paste Fehler. Sorry.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo,
ich gauble es gibt einen Fehler, in der Funktion  unsigned char 
dekrypt_data( char* Data ) Data ist nicht definiert. ich bekomme die 
Meldung: undefined reference to `strtok' überall wo strtok benutzt wird.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank wrote:
> hallo,
> ich gauble es gibt einen Fehler, in der Funktion  unsigned char
> dekrypt_data( char* Data ) Data ist nicht definiert.

Dopch, Data ist definiert. Ist ja ein Funktionsparameter.

> ich bekomme die
> Meldung: undefined reference to `strtok' überall wo strtok
> benutzt wird.

Hast du <string.h> inkludiert?

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank wrote:
> ja


'undefined reference' ist eine Meldung des Linkers, dass er die
Implementierung für strtok nicht finden konnte als er das komplette
Programm aus den Einzelteilen zusammenbauen sollte.

Entweder dir fehlt eine Library, oder in der Systemlibrary ist
strtok tatsächlich nicht enthalten oder bei der Installation
deines C-Systems ist irgendetwas schief gelaufen.
(Oder es gibt noch ein anderes Problem in deinem Code, das aber
mangels verwertbarem Code deinerseits, aus der Ferne nicht
diagnostizierbar ist).

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
er erkennt trotzdem alle anderen Funktionen wie strstr(),strchr() usw..
soll ich dir die ganze Code schicken

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo karl,
strtok ist als  extern char *strtok_r(char *, const char *, char **);
in string.h definiert.
Was soll ich jetzt machen.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und auch in libc.a definiert ,wenn ich grep Befehl benutze

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Trotzdem muss irgendwo ein Wurm drinnen sein.
Ansonsten würde der Linker nicht maulen, dass er strtok nicht
finden kann.

Autor: Frank (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo Karl,
das war mein Fehler ich habe avr-libc-user-manual gelesen und strtok ist 
nicht definiert sondern strtok_r.
Ich habe diese kleine Routine geschrieben und es funktioniert gut aber 
ich möchte auch das die verchiedenen String an der Adresse des 
Arrays(data) gespeichert werden.Mit sprintf habe ich nur das erste 
Zeichen.
ZB:data[0]="ring"
   data[1]="2"
   data[2]="to"
   data[3]="5"

Danke

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

Bewertung
0 lesenswert
nicht lesenswert
static char *strtok_ptr;
#define strtok(a, b) strtok_r(a, b, &strtok_ptr)

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

Bewertung
0 lesenswert
nicht lesenswert

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Frank wrote:
> hallo Karl,
> das war mein Fehler ich habe avr-libc-user-manual gelesen und strtok ist
> nicht definiert sondern strtok_r.

Ah. ok. Das wusste ich nicht. Jörg hat sich schon darum angenommen,
sodass das in Zukunft gefixt wird.

> Ich habe diese kleine Routine geschrieben und es funktioniert gut aber
> ich möchte auch das die verchiedenen String an der Adresse des
> Arrays(data) gespeichert werden.Mit sprintf habe ich nur das erste
> Zeichen.

Logisch funnktioniert das nicht.

> ZB:data[0]="ring"
>    data[1]="2"
>    data[2]="to"
>    data[3]="5"

Wie muss eine Datenstruktur aussehen, die sowas speichern
kann?
Hinweis: Ein 1-dimensionales Array kann es schon mal nicht
sein. Ein 1-dimensinoales Array kann nur 1 String speichern.
Du willst aber viele Strings speichern, also brauchst du
zumindest ein 2-dimensionales Array.


    +---+---+---+---+---+---+---+---+---+
    | r | i | n | g | \0|   |   |   |   |
    +---+---+---+---+---+---+---+---+---+
    | 2 | \0|   |   |   |   |   |   |   |
    +---+---+---+---+---+---+---+---+---+
    | t | o | \0|   |   |   |   |   |   |
    +---+---+---+---+---+---+---+---+---+
    | 5 | \0|   |   |   |   |   |   |   |
    +---+---+---+---+---+---+---+---+---+
    |   |   |   |   |   |   |   |   |   |
    +---+---+---+---+---+---+---+---+---+
    |   |   |   |   |   |   |   |   |   |
    +---+---+---+---+---+---+---+---+---+

Dein data ist aber nichts in der Art und Weise.
Was passiert bei dir:

data sieht so aus:

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+

Am Anfang lässt du sPtr auf &Data zeigen

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   |   |   |   |   |   |   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
     ^
     |     sPtr
     |     +-----+
     +-------o   |
           +-----+

Dann kommt der strtok und identifiziert das erste Wort "ring"
Dieses Wort kopierst du dorthin, wo sPtr hinzeigt

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | i | n | g | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
     ^
     |     sPtr
     |     +-----+
     +-------o   |
           +-----+

anschliessend machst du einen sPtr++ :

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | i | n | g | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
         ^
         | sPtr
         | +-----+
         +---o   |
           +-----+

strtok identifiziert das nächste Wort "2"
Wieder wird es dorthin kopiert, wohin sPtr zeigt

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | 2 | \0| g | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
         ^
         | sPtr
         | +-----+
         +---o   |
           +-----+

und sPtr wieder um 1 erhöht

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | 2 | \0| g | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
             ^
             |
         +---+
         | sPtr
         | +-----+
         +---o   |
           +-----+

Der nächste strtok, das nächste Wort "to"
dorthin kopieren, wohin sPtr zeigt

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | 2 | t | o | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
             ^
             |
         +---+
         | sPtr
         | +-----+
         +---o   |
           +-----+

sPtr, erhöhen

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | 2 | t | o | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
                 ^
                 |
                 +-+
           sPtr    |
           +-----+ |
           |o------+
           +-----+

strtok liefert als nächstes "5". Wieder: dorthin kopieren,
wohin sPtr zeigt

   +---+---+---+---+---+---+---+---+---+---+---+---+---+
   | r | 2 | t | 5 | \0|   |   |   |   |   |   |   |   |
   +---+---+---+---+---+---+---+---+---+---+---+---+---+
                 ^
                 |
                 +-+
           sPtr    |
           +-----+ |
           |o------+
           +-----+

Und so entsteht der String den du siehst.

Wie schon gesagt: Mit einem 1-d char Array kannst du das nicht lösen.
Du brauchst ein 2-d Array.

Autor: Frank (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo karl,
es klappt sehr gut mit dem zweidimensionalen Array.
Ich danke dir

Autor: Frank (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo Karl,
noch ein kleines Problem.Ich bekomme nicht die richtige Werte von Data 
in veschiedenen Stellen.Nur data[0] klappt,für die andere Stelle bekomme 
ich komische Werte. Das ist problematisch,weil ich später die Werte von 
data an eine Struktur zuweisen möchte.
Danke

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schön langsam trickst du dich mit den ganzen Pointern selbst aus :-)

Was spricht dagegen, das ganze ganz einfach mit Indizes
zu machen?

(PS: char data[10[4]
     Der String "ring" besteht aus 5 (!) Buchstaben! Du hast das
     abschliessende '\0' vergessen. Generell lohnt es hier nicht
     mit Speicherplatz zu geizen.)
int main(void)
{
  int i;

  const char str[50] = "ring 2 to 5";

  char data[10][20];
  char* str_tok;
  int NrArgs = 0;

  result = strtok_r( str, " ", &str_tok ); 
  while( result != NULL ) 
  {
    strcpy( data[NrArgs], result );
    NrArgs++;

    result = strtok_r( NULL, " ", %str_tok );
  }

  for( i = 0; i < NrArgs; ++i )
    printf( "Arg %d: '%s'\n", i, data[i] );
}

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.