2016-12-22 2 views
1

Ich habe ein Problem in Bezug auf die Trennung der Inhalte einer Zeichenfolge an eine Funktion übergeben. Die Funktion wird mit einem String wie folgt aufgerufen:Zerlegung von Strings in Strings mit strtok() funktioniert nicht

ADD:Nathaniel:50 

Wo ADD die Protokollnamen sein wird, wird Nathaniel der Schlüssel sein, und 50 wird der Wert sein, die alle mit einem : getrennt.

Mein Code sieht wie folgt aus:

bool add_to_list(char* buffer){ 

    char key[40]; 
    char value[40]; 
    int* token; 

    char buffer_copy[1024]; 
    const char delim[2] = ":"; 

    strcpy(buffer_copy, buffer); 

    token = strtok(NULL, delim); 
    //strcpy(key, token); 

    printf("%d",token); 
    printf("%p",token); 

    while(token != NULL){ 
    token = strtok (NULL, delim); 
    } 
    //strcpy(value, token); 

    printf("%s", key); 
    printf("%s", value); 
    push(key, value); 

    return true; 
} 

Was ich versuche zu tun, speichern Sie jede Taste und Wert in einer separaten Variable, mit strtok(). Beachten Sie, dass ich versuche, den zweiten und dritten Wert (Nathaniel und 50) nicht das erste Bit (ADD) zu speichern.

Wenn ich den Code ausführen, gibt es mir einen Segmentierungsfehler, so vermute ich, dass ich versuche, auf eine ungültige Speicheradresse statt auf einen Wert zuzugreifen. Ich muss nur das zweite und dritte Bit der Zeichenfolge speichern. Kann mir bitte jemand helfen?

EDIT: ich den Code geändert haben wie folgt aussehen:

bool add_to_list(char* buffer){ 

char *key, *value, *token; 

const char *delim = ":"; 

token = strtok(buffer, delim); 

//printf("%d",token); 
printf("%s",token); 

key = strtok(NULL, delim); 
value = strtok(NULL, delim); 

printf("%s", key); 
printf("%s", value); 
//push(key, value); 

return true; 
} 

Aber ich bin immer noch die gleiche Segmentierungsfehler bekommen (core dumped) Fehler

+1

Sie speichern nie etwas in 'Schlüssel' oder' Wert'. – Barmar

+2

'int * token;' -> 'char * token;' – BLUEPIXY

+1

'const char [2] delim' ->' const char * delim' – abligh

Antwort

4

Der erste Aufruf von strtok() Bedürfnisse sorgen die zu scannende Zeichenfolge Sie verwenden nur NULL für die wiederholten Aufrufe, so wird es den Rest der Zeichenfolge weiter verarbeiten. SO sollte der erste Aufruf sein:

token = strtok(buffer_copy, delim); 

Wenn Sie dann den Schlüssel und den Wert erhalten möchten, müssen Sie sie auf die Felder kopieren:

token = strtok(NULL, delim); 
key = strcpy(token); 
token = strtok(NULL, delim); 
value = strcpy(token); 

Sie keine Schleife benötigen, da Sie möchten nur diese beiden Werte extrahieren.

Eigentlich brauchen Sie nicht key und value als Arrays zu deklarieren, können Sie Zeiger verwenden:

char *key, *value; 

Dann können Sie tun:

token = strtok(buffer_copy, delim); 
key = strtok(NULL, delim); 
value = strtok(NULL, delim); 
+0

Ich bekomme einige Warnungen in Bezug auf: Warnung: Zuweisung von inkompatiblen Zeigertyp [-Wincompatible-Zeiger-Typen] token = strtok (buffer_copy, delim); Was passiert hier und gibt es eine Möglichkeit, den Fehler zu entfernen? –

+1

'token' sollte' char * 'sein, nicht' int * '. – Barmar

1

Ihr Hauptproblem ist, dass, wenn Sie erster Aufruf strtok, der erste Parameter sollte die Zeichenfolge sein, die Sie analysieren möchten, also nicht:

strcpy(buffer_copy, buffer); 
token = strtok(NULL, delim); 

aber

strcpy(buffer_copy, buffer); 
token = strtok(buffer_copy, delim); 

Zusätzlich, wenn Sie die Token in Ihrem while Schleife erkennen, werden Sie sie wegzuwerfen. Sie möchten etwas an diesem Punkt tun (oder einfach die Schleife ausrollen und dreimal strtok aufrufen).

auch:

const char* delim = ":"; 

wäre eine konventionellere Weise eine NUL terminierten String sicherzustellen, als:

const char delim[2] = ":"; 

Sehen Sie sich auch strtok_r nicht strtok als strtok verwendet, ist nicht Thread-sicher und schrecklich. Obwohl Sie hier keine Threads verwenden (so scheint es), können Sie auch in die Praxis einsteigen.

+0

Können Sie bitte erklären, wie Sie die Funktion strtok_r verwenden? Ich versuche Informationen darüber zu finden, aber ich finde es schwierig zu verstehen. Auch mein System wird wie ein kleiner Server sein, also werde ich mehrere Threads haben, daher bin ich fasziniert über die Verwendung der sicheren Version, plus seine gute Ethik –

+0

Re 'strtok_r', die Handbuchseite ist eine nützliche Ressource, aber hier ist Was du machen solltest. Fügen Sie für jede Zeichenketten-Tokenisierung (dh einmal im Beispiel hier) 'char * save = NULL;' vor der ersten Verwendung hinzu (technisch ist die Initialisierung optional), dann fügen Sie '& save' als zusätzlichen Parameter zu jeder Verwendung hinzu von 'strtok' in dieser Tokenisierung, und ändere' strtok' in 'strtok_r'. Das bedeutet, dass 'strtok_r' seinen Zustand zwischen den Aufrufen in' save' und nicht in einem internen statischen Puffer speichert, so dass Sie Thread-Sicherheit haben. – abligh

Verwandte Themen