plus cpp c segmentation-fault strtok

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:

  1. hello apunta a una cadena literal, que debe ser tratada como inmutable. (Podría vivir en la memoria de solo lectura). Ya que strtok_r muta su cadena de argumento, no puedes usar hello con ella.

  2. Llama a strtok_r solo una vez y no inicializa su matriz de tokens 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 das NULL como el primer parámetro.
  • strtok_r toma un char ** como el tercer parámetro. tokens es una matriz de valores de 50 caracteres char * . Cuando pasas tokens a strtok_r() , lo que se pasa es un valor char ** 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 el char *last; y use &last como el tercer parámetro para strtok_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.