¿Cómo divide strtok() la cadena en tokens en C?
Por favor explíqueme el funcionamiento de strtok()
la función. El manual dice que rompe la cuerda en fichas. No puedo entender en el manual lo que realmente hace.
Agregué relojes str
y *pch
para verificar su funcionamiento cuando ocurrió el primer ciclo while, el contenido de str
era solo "esto". ¿Cómo se imprimió en la pantalla el resultado que se muestra a continuación?
/* strtok example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
Producción:
División de cadena "- Esta, una cadena de muestra". en fichas: Este a muestra cadena
la función de tiempo de ejecución strtok funciona así
la primera vez que llamas a strtok proporcionas una cadena que deseas tokenizar
char s[] = "this is a string";
en la cadena anterior el espacio parece ser un buen delimitador entre palabras, así que usémoslo:
char* p = strtok(s, " ");
lo que sucede ahora es que se busca 's' hasta que se encuentra el carácter de espacio, se devuelve el primer token ('this') y p apunta a ese token (cadena)
para obtener el siguiente token y continuar con la misma cadena, se pasa NULL como primer argumento ya que strtok mantiene un puntero estático a la cadena pasada anterior:
p = strtok(NULL," ");
p ahora apunta a 'es'
y así sucesivamente hasta que no se puedan encontrar más espacios, luego la última cadena se devuelve como la última "cadena" del token.
Lo más conveniente es escribirlo así para imprimir todos los tokens:
for (char *p = strtok(s," "); p != NULL; p = strtok(NULL, " "))
{
puts(p);
}
EDITAR:
Si desea almacenar los valores devueltos, strtok
debe copiar el token a otro búfer, por ejemplo, strdup(p);
ya que la cadena original (señalada por el puntero estático dentro strtok
) se modifica entre iteraciones para devolver el token.
strtok()
divide la cadena en tokens. es decir, comenzar desde cualquiera de los delimitadores hasta el siguiente sería su único token. En su caso, el token inicial será "-" y terminará con el siguiente espacio "". Luego, el siguiente token comenzará en " " y terminará en ",". Aquí obtienes "Esto" como salida. De manera similar, el resto de la cadena se divide en tokens de espacio a espacio y finalmente termina el último token en "."
strtok
mantiene una referencia interna estática que apunta al siguiente token disponible en la cadena; si le pasa un puntero NULL, funcionará a partir de esa referencia interna.
Ésta es la razón strtok
por la que no es reentrante; tan pronto como le pasa un nuevo puntero, esa antigua referencia interna queda destruida.
strtok
no cambia el parámetro en sí ( str
). Almacena ese puntero (en una variable estática local). Luego puede cambiar a qué apunta ese parámetro en llamadas posteriores sin que se devuelva el parámetro. (Y puede avanzar ese puntero que ha conservado como sea necesario para realizar sus operaciones).
Desde la strtok
página POSIX:
Esta función utiliza almacenamiento estático para realizar un seguimiento de la posición actual de la cadena entre llamadas.
Existe una variante segura para subprocesos ( strtok_r
) que no hace este tipo de magia.