Kann jemand erklären, warum ich im folgenden Beispiel einen Segmentierungsfehler erhalte?
#include <stdio.h>
#include <string.h>
int main(void) {
char *hello = "Hello World, Let me live.";
char *tokens[50];
strtok_r(hello, " ,", tokens);
int i = 0;
while(i < 5) {
printf("%s\n", tokens[i++]);
}
}
codaddict
Versuche dies:
#include <stdio.h>
#include <string.h>
int main(void) {
char hello[] = "Hello World, Let me live."; // make this a char array not a pointer to literal.
char *rest; // to point to the rest of the string after token extraction.
char *token; // to point to the actual token returned.
char *ptr = hello; // make q point to start of hello.
// loop till strtok_r returns NULL.
while(token = strtok_r(ptr, " ,", &rest)) {
printf("%s\n", token); // print the token returned.
ptr = rest; // rest contains the left over part..assign it to ptr...and start tokenizing again.
}
}
/*
Output:
Hello
World
Let
me
live.
*/
Dieses Beispiel gibt mir einen Segfault in der printf-Zeile. gdb print token zeigt 0xffffffffffffdad0 Bekomme auch diese beiden Warnungen, wenn ich proj1.c:33:2 kompiliere: Warnung: implizite Deklaration der Funktion ‘strtok_r’ [-Wimplicit-function-declaration] proj1.c:33:14: Warnung: Zuweisung macht Zeiger aus Integer ohne Umwandlung [enabled by default]
– Nathan Schwermann
1. Oktober 2012 um 0:48 Uhr
Entschuldigung, ich bin ein Neuling, warum sollte es nicht sein char *ptr = Hello; mit einem großen H? Außerdem sagt Aloks Antwort, dass das erste Mal, wenn der erste Parameter “tokenisiert” werden muss, und dann nachfolgende Aufrufe NULL sein müssen, aber es scheint, dass Ihr Beispiel es nur in die eine Richtung in der While-Schleife aufruft? Danke für den Code btw
– SSH Dies
17. Dezember 2012 um 22:48 Uhr
*ptr = hello; Weil hello bezieht sich auf char hello[]....
– MrHIDEn
9. Januar 2015 um 14:06 Uhr
Sie müssen anrufen strtok_r in einer Schleife. Das erste Mal, wenn Sie ihm die Zeichenfolge geben, die in Tokens umgewandelt werden soll, dann geben Sie sie an NULL als erster Parameter.
strtok_r nimmt ein char ** als dritter Parameter. tokens ist ein Array von 50 char * Werte. Wenn du passierst tokens zu strtok_r()was bestanden wird, ist a char ** Wert, der auf das erste Element dieses Arrays zeigt. Das ist in Ordnung, aber Sie verschwenden 49 der Werte, die überhaupt nicht verwendet werden. Du solltest haben char *last; und verwenden &last als dritter Parameter zu strtok_r().
strtok_r() ändert sein erstes Argument, also können Sie ihm nichts übergeben, was nicht geändert werden kann. Zeichenfolgenliterale in C sind schreibgeschützt, daher benötigen Sie etwas, das geändert werden kann: char hello[] = "Hello World, Let me live."; zum Beispiel.
Danke für die Antwort. Ich wünschte, SO darf mehrere Antworten als richtig markieren. 🙂
– Phulore R – Profil 2
9. Februar 2010 um 7:00 Uhr
@Scrub: freut mich, behilflich zu sein. Stellen Sie sicher, dass Sie meinen zweiten Punkt oben verstehen (ca char *tokens[50]; gleichwertig sein char ** bei Übergabe an eine Funktion).
– Alok Singhal
9. Februar 2010 um 7:04 Uhr
Rettete mich; +1, um mich daran zu erinnern, dass Param 1 nicht sein kann const char *. Für andere: Geben Sie keine Daten aus der .RODATA-Sektion ein. Oder: Probieren Sie aus, ob es mit funktioniert strcpy‘ing vorher in einen Temp-Puffer.
– Joel
25. Juni 2021 um 6:27 Uhr
Ein Haufen Dinge falsch:
hello zeigt auf ein Zeichenfolgenliteral, das als unveränderlich behandelt werden muss. (Es könnte im Nur-Lese-Speicher leben.) Seitdem strtok_r mutiert seine Argumentzeichenfolge, die Sie nicht verwenden können hello damit.
Du rufst an strtok_r nur einmal und initialisieren Sie Ihre nicht tokens Array, um auf irgendetwas zu zeigen.
Versuche dies:
#include <stdio.h>
#include <string.h>
int main(void) {
char hello[] = "Hello World, Let me live.";
char *p = hello;
char *tokens[50];
int i = 0;
while (i < 50) {
tokens[i] = strtok_r(p, " ,", &p);
if (tokens[i] == NULL) {
break;
}
i++;
}
i = 0;
while (i < 5) {
printf("%s\n", tokens[i++]);
}
return 0;
}
Danke für die Antwort. Ich wünschte, SO darf mehrere Antworten als richtig markieren. 🙂
– Phulore R – Profil 2
9. Februar 2010 um 7:01 Uhr
strtok_r versucht, Nullzeichen in hallo zu schreiben (was illegal ist, da es sich um eine konstante Zeichenfolge handelt).
Anssi
Sie haben die Verwendung von strtok_r falsch verstanden. Bitte prüfen Sie das Beispiel und Dokumentation
Ich denke es könnte der sein char *tokens[50]; weil Sie es als Zeiger deklarieren, wenn es bereits ein Zeiger ist. Ein Array ist bereits bei der Deklaration ein Zeiger. Du meinst zu sagen char tokens[50];. Das sollte reichen.
11862900cookie-checkSegmentierungsfehler bei Verwendung von strtok_ryes