cpp - strtok c++>
Fallo de segmentación al usar strtok_r (6)
Creo que podrían ser las char *tokens[50];
porque lo estás declarando puntero cuando ya es un puntero. Una matriz ya es un puntero a la declaración. Quieres decir las char tokens[50];
. Eso debería hacer el truco.
¿Alguien puede explicar por qué me aparece una falla de segmentación en el siguiente ejemplo?
#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++]);
}
}
Has entendido el uso de strtok_r incorrectamente. Por favor revise este example y la documentación.
Y prueba y ve esto:
#include <stdio.h>
#include <string.h>
int main(void)
{
char hello[] = "Hello World, let me live.";
char *tmp;
char *token = NULL;
for(token = strtok_r(hello, ", ", &tmp);
token != NULL;
token = strtok_r(NULL, ", ", &tmp))
{
printf("%s/n", token);
}
return 0;
}
Prueba esto:
#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.
*/
Un montón de cosas mal:
hello
apunta a una cadena literal, que debe ser tratada como inmutable. (Podría vivir en la memoria de solo lectura). Ya questrtok_r
muta su cadena de argumento, no puedes usarhello
con ella.Llama a
strtok_r
solo una vez y no inicializa su matriz detokens
para señalar nada.
Prueba esto:
#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;
}
strtok_r intenta escribir caracteres nulos en hola (lo cual es ilegal porque es una cadena constante)
- Necesitas llamar a
strtok_r
en un bucle. La primera vez que le asignas la cadena a ser tokenizada, entonces le dasNULL
como el primer parámetro. -
strtok_r
toma unchar **
como el tercer parámetro.tokens
es una matriz de valores de 50 caractereschar *
. Cuando pasastokens
astrtok_r()
, lo que se pasa es un valorchar **
que apunta al primer elemento de esa matriz. Esto está bien, pero está perdiendo 49 de los valores que no se utilizan en absoluto. Deberías tener elchar *last;
y use&last
como el tercer parámetro parastrtok_r()
. -
strtok_r()
modifica su primer argumento, por lo que no puede pasarle algo que no pueda ser modificado. Los literales de cadena en C son de solo lectura, por lo que necesita algo que pueda modificarse:char hello[] = "Hello World, Let me live.";
por ejemplo.