¿Cómo divide strtok() la cadena en tokens en C?

Resuelto asked hace 13 años • 16 respuestas

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 stry *pchpara verificar su funcionamiento cuando ocurrió el primer ciclo while, el contenido de strera 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
 avatar Oct 08 '10 18:10
Aceptado

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, strtokdebe 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.

AndersK avatar Oct 08 '2010 11:10 AndersK

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 "."

Sachin Shanbhag avatar Oct 08 '2010 11:10 Sachin Shanbhag

strtokmantiene 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 strtokpor la que no es reentrante; tan pronto como le pasa un nuevo puntero, esa antigua referencia interna queda destruida.

John Bode avatar May 17 '2012 18:05 John Bode

strtokno 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 strtokpá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.

Mat avatar May 17 '2012 18:05 Mat