Forum: Compiler & IDEs String Bearbeitung


von Frank (Gast)


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.

von Karl H. (kbuchegg)


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().

von Frank (Gast)


Lesenswert?

nein es kann unterschiedlihe Länge haben.

von Karl H. (kbuchegg)


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.

von Frank (Gast)


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

von Karl H. (kbuchegg)


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.

1
#include <stdio.h>
2
#include <string.h>
3
4
char Command[20];
5
char CmdArg1[20];
6
char CmdArg2[20];
7
char CmdArg3[20];
8
9
unsigned char dekrypt_data( char* Data )
10
{
11
  int Len = strlen( Data );
12
  char* pPtr;
13
14
  Command[0] = '\0';
15
  CmdArg1[0] = '\0';
16
  CmdArg2[0] = '\0';
17
  CmdArg3[0] = '\0';
18
19
  // Extrahiere das Commando, falls es einens gibt
20
  pPtr = strtok( Data, " " );
21
  if( pPtr == NULL )
22
    return 0;
23
24
  strncpy( Command, pPtr, sizeof( Command ) );
25
26
  // Extrahiere das Erste Argument, falls es eines gibt
27
  pPtr = strtok( NULL, " " );
28
  if( pPtr == NULL )
29
    return 1;
30
31
  strncpy( CmdArg1, pPtr, sizeof( Command ) );
32
33
  // Extrahiere das Zweite Argument, falls es eines gibt
34
  pPtr = strtok( NULL, " " );
35
  if( pPtr == NULL )
36
    return 2;
37
38
  strncpy( CmdArg2, pPtr, sizeof( Command ) );
39
40
  // Extrahiere das Dritte Argument, falls es eines gibt
41
  pPtr = strtok( NULL, " " );
42
  if( pPtr == NULL )
43
    return 3;
44
45
  strncpy( CmdArg3, pPtr, sizeof( Command ) );
46
47
  return 4;
48
}
49
50
51
int main()
52
{
53
  char Line[] = "SEND AA BBB CC";
54
  unsigned char NrArgs;
55
56
  NrArgs = dekrypt_data( Line );
57
58
  printf( "Nr of recognized Strings: %d\n", NrArgs );
59
  if( NrArgs > 0 )
60
    printf( "Command: %s\n", Command );
61
  if( NrArgs > 1 )
62
    printf( "Argument1: %s\n", CmdArg1 );
63
  if( NrArgs > 2 )
64
    printf( "Argument1: %s\n", CmdArg2 );
65
  if( NrArgs > 3 )
66
    printf( "Argument1: %s\n", CmdArg3 );
67
}

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.

von Karl H. (kbuchegg)


Lesenswert?

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

von Frank (Gast)


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.

von Karl H. (kbuchegg)


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?

von Frank (Gast)


Lesenswert?

ja

von Karl H. (kbuchegg)


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).

von Frank (Gast)


Lesenswert?

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

von Frank (Gast)


Lesenswert?

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

von Frank (Gast)


Lesenswert?

und auch in libc.a definiert ,wenn ich grep Befehl benutze

von Karl H. (kbuchegg)


Lesenswert?

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

von Frank (Gast)


Angehängte Dateien:

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

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

1
static char *strtok_ptr;
2
#define strtok(a, b) strtok_r(a, b, &strtok_ptr)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?


von Karl H. (kbuchegg)


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.

von Frank (Gast)


Lesenswert?

hallo karl,
es klappt sehr gut mit dem zweidimensionalen Array.
Ich danke dir

von Frank (Gast)


Angehängte Dateien:

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

von Karl H. (kbuchegg)


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.)
1
int main(void)
2
{
3
  int i;
4
5
  const char str[50] = "ring 2 to 5";
6
7
  char data[10][20];
8
  char* str_tok;
9
  int NrArgs = 0;
10
11
  result = strtok_r( str, " ", &str_tok ); 
12
  while( result != NULL ) 
13
  {
14
    strcpy( data[NrArgs], result );
15
    NrArgs++;
16
17
    result = strtok_r( NULL, " ", %str_tok );
18
  }
19
20
  for( i = 0; i < NrArgs; ++i )
21
    printf( "Arg %d: '%s'\n", i, data[i] );
22
}

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.