¿Cómo funciona la función strtok en C? [duplicate]

4 minutos de lectura

¿Como funciona la funcion strtok en C duplicate
usuario2426316

Encontré este programa de muestra que explica el strtok función:

#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;
}

Sin embargo, no veo cómo es posible que esto funcione.

como es posible que pch = strtok (NULL, " ,.-"); devuelve un nuevo token. Quiero decir, estamos llamando strtokcon NULL . Esto no tiene mucho sentido para mí.

  • es.cppreference.com/w/c/string/byte/strtok

    – Sander de Dycker

    13 de enero de 2014 a las 17:13

  • Encontré este programa de muestra que explica la función strtok no es el ejemplo lo que explica, sino la documentación, por lo que le gustaría leer aquí: man7.org/linux/man-pages/man3/strtok.3.html

    – alk

    13 de enero de 2014 a las 17:13


  • Y no tiene sentido para nadie.. así que strtok_r() fue creado…

    – vrdhn

    13 de enero de 2014 a las 17:14


  • O.T.: es int main (void) por cierto.

    – alk

    13 de enero de 2014 a las 17:15

1647540247 95 ¿Como funciona la funcion strtok en C duplicate
floris

Dos cosas que debes saber sobre strtok. Como se mencionó, “mantiene el estado interno”. También eso estropea la cuerda que le das de comer. Esencialmente, escribirá un '\0' donde encuentra el token que proporcionó y devuelve un puntero al comienzo de la cadena. Internamente mantiene la ubicación del último token; y la próxima vez que lo llame, comenzará desde allí.

El corolario importante es que no se puede utilizar strtok en un const char* "hello world"; tipo de cadena, ya que obtendrá una violación de acceso cuando modifique el contenido de un const char* cuerda.

Lo “bueno” de strtok es que en realidad no copia cadenas, por lo que no necesita administrar la asignación de memoria adicional, etc. Pero a menos que comprenda lo anterior, tendrá problemas para usarlo correctamente.

Ejemplo: si tiene “esto, es, una, cadena”, llamadas sucesivas a strtok generará punteros de la siguiente manera (el ^ es el valor devuelto). Tenga en cuenta que el '\0' se agrega donde se encuentran las fichas; esto significa que la cadena de origen se modifica:

t  h  i  s  ,  i  s  ,  a  ,  s  t  r  i  n  g \0         this,is,a,string

t  h  i  s  \0 i  s  ,  a  ,  s  t  r  i  n  g \0         this
^
t  h  i  s  \0 i  s  \0 a  ,  s  t  r  i  n  g \0         is
               ^
t  h  i  s  \0 i  s  \0 a  \0 s  t  r  i  n  g \0         a
                        ^
t  h  i  s  \0 i  s  \0 a  \0 s  t  r  i  n  g \0         string
                              ^

Espero que tenga sentido.

strtok mantiene el estado interno. Cuando lo llama con no NULL, se reinicializa para usar la cadena que proporciona. Cuando lo llamas con NULL usa esa cadena, y cualquier otro estado que tenga actualmente para devolver el siguiente token.

por la manera strtok funciona, debe asegurarse de vincular con una versión multiproceso del tiempo de ejecución de C si está escribiendo una aplicación multiproceso. Esto asegurará que cada subproceso obtenga su propio estado interno para strtok.

los strtok() La función almacena datos entre llamadas. Utiliza esos datos cuando lo llama con un puntero NULL.

Desde http://www.cplusplus.com/reference/cstring/strtok/ :

El punto donde se encontró el último token lo mantiene internamente la función que se usará en la próxima llamada (no se requieren implementaciones de bibliotecas particulares para evitar carreras de datos).

  • La mayoría de los tiempos de ejecución modernos almacenan el estado en el almacenamiento local de subprocesos. Lo que significa que es seguro para subprocesos pero no seguro cuando se usa de forma reentrante.

    –David Heffernan

    13 de enero de 2014 a las 17:14

  • Gracias por la corrección.

    –Andy Thomas

    13 de enero de 2014 a las 17:16

los strtok La función almacena datos en una variable estática interna que se comparte entre todos los subprocesos.

Para la seguridad del hilo, debe usar strtok_r

Desde http://www.opensource.apple.com/source/Libc/Libc-167/string.subproj/strtok.c

echa un vistazo a static char *last;

char *
strtok(s, delim)
    register char *s;
    register const char *delim;
{
    register char *spanp;
    register int c, sc;
    char *tok;
    static char *last;


    if (s == NULL && (s = last) == NULL)
        return (NULL);

    /*
     * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
     */
cont:
    c = *s++;
    for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
        if (c == sc)
            goto cont;
    }

    if (c == 0) {       /* no non-delimiter characters */
        last = NULL;
        return (NULL);
    }
    tok = s - 1;

    /*
     * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
     * Note that delim must have one NUL; we stop if we see that, too.
     */
    for (;;) {
        c = *s++;
        spanp = (char *)delim;
        do {
            if ((sc = *spanp++) == c) {
                if (c == 0)
                    s = NULL;
                else
                    s[-1] = 0;
                last = s;
                return (tok);
            }
        } while (sc != 0);
    }
    /* NOTREACHED */
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad