Menú
Está libre
registro
hogar  /  Problemas/ Strtok s c descripción. Man strtok_r (3): recuperando elementos (tokens) de una cadena

Descripción de Strtok s c. Man strtok_r (3): recuperando elementos (tokens) de una cadena

4 respuestas

Dos cosas que debes saber sobre strtok. Como se mencionó, "mantiene un estado interno". Además, él arruinó la línea, la alimenta... Básicamente, escribirá "\ 0" donde encontrará el marcador que proporcionó y devolverá un puntero al principio de la línea. Internamente, mantiene la ubicación del último token; y la próxima vez que lo llame, comenzará desde allí.

Un corolario importante es que no puede usar strtok en un const char * "hello world"; ya que obtendrá una infracción de acceso cuando cambie el contenido de la cadena const char *.

Lo "bueno" de strtok es que en realidad no copia cadenas, por lo que no es necesario administrar asignaciones de memoria adicionales, etc. Pero si no comprende lo anterior, tendrá problemas para usarlo.

Ejemplo. Si tiene "esto, es, una cadena", las sucesivas llamadas a strtok generarán punteros como este (el valor ^ es el valor de retorno). Tenga en cuenta que se agrega "\ 0" donde se encuentran los tokens; esto significa que cadena fuente cambió:

Este, es, a, cadena \ 0 esto, es, a, cadena esto \ 0 es, a, cadena \ 0 esto ^ esto \ 0 es \ 0 a, cadena \ 0 es ^ esto \ 0 es \ 0 a \ 0 cadena \ 0 a ^ este \ 0 es \ 0 a \ 0 cadena \ 0 cadena ^

Espero que esto tenga sentido.

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

El punto en el que se encontró el último token se almacena internamente mediante una función que se utilizará en la próxima llamada (no se requiere una implementación específica de la biblioteca para evitar fallas de datos).

strtok mantiene el estado interno. Cuando lo llama con non-NULL, se reinicializa para usar la cadena que proporcionó. Cuando lo llama con NULL, usa esa cadena y cualquier otro estado que esté recibiendo actualmente para devolver el siguiente token.

Debido a cómo funciona strtok, debe asegurarse de que está vinculando a la versión multiproceso del tiempo de ejecución de C si escribe aplicación multiproceso... Esto asegura que cada hilo tenga su propio estado interno para strtok.

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

Para la seguridad de los subprocesos, debe usar strtok_r

Eche un vistazo a static char * last;

Char * strtok (s, delim) registra char * s; registrar const char * delim; (registrar char * spanp; registrar int c, sc; char * tok; static char * last; if (s == NULL && (s = last) == NULL) return (NULL); / * * Saltar (span) inicial delimitadores (s + = strspn (s, delim), especie de). * / cont: c = * s ++; for (spanp = (char *) delim; (sc = * spanp ++)! = 0;) (if (c == sc) goto cont;) if (c == 0) (/ * sin caracteres no delimitadores * / last = NULL; return (NULL);) tok = s - 1; / * * Scan token (buscar delimitadores: s + = strcspn (s, delim), más o menos). * Tenga en cuenta que delim debe tener un NUL; también nos detenemos si vemos eso. * / 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);) / * NO ALCANZADO * /)

para compartir

#incluir char * strtok (char * str1, const char * str2);

La función strtok () devuelve un puntero al siguiente token de la cadena a la que apunta el parámetro str1... Caracteres que componen la cadena a la que se dirige el parámetro str2, son delimitadores que definen un token. Si no hay ningún token para devolver, se devuelve un puntero nulo.

En la versión C99 a los parámetros str1 y str2 restringir calificador aplicado.

Para dividir una cadena en tokens, la primera vez que se llama a la función strtok (), el parámetro str1 debe apuntar al comienzo de esta línea. En llamadas posteriores a la función como parámetro str1 necesitas usar un puntero nulo. De esta forma, toda la línea se divide en tokens.

Cada vez que se llama a la función strtok (), puede usar diferentes conjuntos separadores.

Ejemplo

Este programa divide la línea "La hierba es verde, el sol brilla" en fichas separadas por espacios y comas. El resultado sera

Hierba | verde | sol | brilla #incluir #incluir int main (void) (char * p; p = strtok ("La hierba se pone verde, el sol brilla", ""); printf (p); do (p = strtok ("\ 0", ","); if (p) printf ("|% s", p);) while (p); return 0;)

Sintaxis:

#incluir
char * strtok (char * str, const char * sep);

Argumentos:

str es un puntero a la cadena que se va a dividir.
sep es un puntero a una cadena que contiene un conjunto de caracteres separadores.

Valor devuelto:

NULL: si la cadena str no se puede dividir en partes.
Puntero al primer carácter de la parte seleccionada de la cadena.

Descripción:

La función strtok selecciona la siguiente parte de la cadena apuntada por el argumento str, separada por uno de los caracteres separadores especificados en la cadena apuntada por el argumento sep. Una llamada secuencial a la función strtok da como resultado la división de la cadena str en partes (tokens).

“La primera llamada a la función strtok especifica el comienzo de la cadena separada (str) y el comienzo de la cadena que contiene separadores (sep). Primero, la función strtok itera a través de los caracteres en str y busca un carácter que no esté contenido en la cadena de separación sep. Si se encuentra un carácter de final de línea en str antes de que se encuentre un carácter no incluido en sep, str no se puede dividir en partes y se devuelve un puntero nulo (NULL). Si se encuentra tal carácter, se considera el comienzo de la primera parte de la cadena str ".

A continuación, la función strtok busca el separador, es decir, el carácter incluido en la cadena sep. Si no se encuentra dicho carácter, se considera que la cadena str consta de una parte y la división posterior de la cadena str devolverá un puntero nulo. Si se encuentra tal símbolo. luego se reemplaza con un carácter nulo (carácter de fin de línea). A continuación, la función strtok recuerda la posición actual (un puntero al carácter desde el que comenzará la búsqueda de la siguiente parte de la cadena) y devuelve un puntero al principio de la primera parte seleccionada de la cadena.

Si la función strtok devolvió un puntero no nulo, puede continuar dividiendo str en partes. Para continuar dividiendo la cadena, se vuelve a llamar a la función strtok, pero en lugar de un puntero a la cadena a dividir, se especifica NULL como primer aumento. En este caso, la función strtok continuará dividiéndose desde la dirección recordada. El algoritmo de partición sigue siendo el mismo.

Ejemplo:

En el ejemplo, la cadena “test1 / test2 / test3 / test4” se divide en partes por el separador “/” usando la función strtok. El resultado de la división se envía a la consola.

Resultado:

Salida de consola:


char far * far _fstrtok (const char far * str1, const char far * str2)

Descripción:

La función strtok () devuelve un puntero al siguiente token en la cadena apuntada por str1. Los caracteres de la cadena a la que apunta str2 se utilizan como delimitadores para definir el token. Si no se encuentra el token, se devuelve NULL.

La primera llamada a strtok () utiliza str1 como puntero. Las siguientes llamadas utilizan NULL como primer argumento. Por lo tanto, se puede tokenizar toda la línea.

Es importante entender que la función strtok () modifica la cadena apuntada por str1. Cada vez que se encuentra un token, se coloca un carácter nulo donde se encontró el delimitador. De esta forma, strtok () avanza a lo largo de la línea.

Cada vez que llame a strtok (), puede variar el conjunto de delimitadores.

La función _fstrtok () es la versión FAR de la función en cuestión.

El siguiente programa divide la cadena "El soldado de verano, el patriota del sol" en fichas, utilizando espacios y comas como delimitadores. Como resultado de la operación del programa, se generará una línea de la siguiente forma: “El | verano | soldado | el | sol | patriota ".
#incluir
#incluir
int main (vacío)
{
char * p;
p = strtok ( "El soldado de verano, el patriota del sol", " " ) ;
printf (p);
hacer (
p = strtok (" \0 " , ", " ) ;
if (p) printf ("|% s", p);
) mientras (p);
return 0;
}

Otro alias

strtok

VISIÓN DE CONJUNTO

#incluir

char * strtok (char *str, const char *delimitar);
char * strtok_r (char *str, const char *delimitar, char **saveptr);

Requisitos de macro de prueba de propiedad para glibc (consulte la p. feature_test_macros(7)):

strtok_r(): _SVID_SOURCE || _BSD_SOURCE || _POSIX_C_SOURCE> = 1 || _XOPEN_SOURCE || _POSIX_SOURCE

DESCRIPCIÓN

Función strtok() divide la cadena en una secuencia de cero o más tokens no vacíos. En la primera llamada strtok() la cadena analizada debe especificarse en el argumento str... En cada llamada posterior que analiza la misma cadena, el valor str debe ser NULO.

En el argumento delimitar se especifica un conjunto de bytes, que se consideran separadores de token en la cadena analizada. La persona que llama puede especificar diferentes líneas en delimitar en llamadas posteriores al analizar la misma cadena.

Cada llamada strtok() devuelve un puntero a una cadena terminada en nulo que contiene el siguiente token. Esta línea no incluye un byte delimitador. Si no hay más tokens, entonces strtok() devuelve NULL.

Secuencia de llamada strtok(), que opera en una sola cadena, mantiene un puntero que define el punto en el que comenzar a buscar el siguiente token. Primera llamada strtok() asigna a este puntero una referencia al primer byte de la cadena. El comienzo del siguiente token se determina buscando hacia adelante en str el siguiente byte no es un delimitador. Si se encuentra un byte, se toma como el comienzo del siguiente token. Si no se encuentra dicho byte, no hay más tokens y strtok() devuelve NULL (para una cadena vacía o que consta solo de delimitadores en este caso, se devolverá NULL en la primera llamada strtok()).

El final de cada token se busca hacia adelante hasta que se encuentra un byte delimitador o un byte nulo de terminación ("\ 0"). Si se encuentra un byte delimitador, se reemplaza con un byte nulo para terminar el token actual, y strtok() almacena un puntero al siguiente byte; este puntero se utilizará como punto de partida al buscar el siguiente token. En este caso strtok() devuelve un puntero al principio del token encontrado.

De la descripción anterior, se deduce que una secuencia de dos o más bytes separadores contiguos en la línea escaneada se considera un separador y los bytes separadores al principio o al final de la línea se ignoran. En otras palabras, los tokens regresaron strtok() son siempre líneas no vacías. Es decir, por ejemplo, si hay una línea " aaa ;; bbb,", Luego llamadas posteriores strtok() con los separadores de línea especificados " ;, "Devolvería las líneas" aaa" y " bbb"Seguido de un puntero nulo.

Función strtok_r() es la versión reentrante strtok(). Argumento saveptr es un puntero a una variable char * que se usa internamente strtok_r() para tener en cuenta el contexto entre llamadas posteriores al analizar la misma cadena.

En la primera llamada strtok_r() sentido str debe apuntar a la cadena para analizar, y el valor saveptr ignorado. En llamadas posteriores, el valor str debe ser NULL y el valor saveptr no debería haber cambiado desde la llamada anterior.

Se pueden analizar diferentes cadenas al mismo tiempo con múltiples ejecuciones strtok_r() con diferentes argumentos saveptr.

VALOR DEVUELTO

Funciones strtok() y strtok_r() devuelve un puntero al siguiente token, o NULL si no hay más tokens.

ATRIBUTOS

Para obtener una descripción de los términos de esta sección, consulte atributos(7).
Interfaz Atributo Sentido
strtok() inofensividad en hilosinseguro (MT-Carrera insegura: strtok)
strtok_r() inofensividad en hilosinofensivo (MT-Safe)

CUMPLIMIENTO

strtok() POSIX.1-2001, POSIX.1-2008, C89, C99, SVr4, 4.3BSD. strtok_r() POSIX.1-2001, POSIX.1-2008.

DEFECTOS

Utilice estas funciones con cuidado. Tenga en cuenta que: * Estas funciones modifican su primer argumento. * Estas funciones no se pueden utilizar con cadenas constantes. * Se pierde la identidad del byte delimitador. * Al analizar la función strtok() usa un búfer estático, por lo que no es seguro para subprocesos. Usar strtok_r() en este caso.

EJEMPLO

El programa siguiente usa bucles anidados que llaman strtok_r() para dividir la cadena en sus tokens constituyentes. En el primer parámetro línea de comando se especifica la cadena analizada. El segundo parámetro especifica el (los) byte (s), el separador utilizado para dividir la cadena en tokens "compuestos". El tercer parámetro especifica el (los) byte (s), el separador que se usa para separar los tokens "compuestos" en subtokens.

Un ejemplo de la salida del programa:

$./a.out "a / bbb /// cc; xxx: yyy:" ":;" "/" 1: a / bbb /// cc -> a -> bbb -> cc 2: xxx -> xxx 3: yyy -> yyy

Código fuente del programa

#incluir #incluir #incluir int main (int argc, char * argv) (char * str1, * str2, * token, * subtoken; char * saveptr1, * saveptr2; int j; if (argc! = 4) (fprintf (stderr, "Uso:% s string delim subdelim \ n ", argv); exit (EXIT_FAILURE);) for (j = 1, str1 = argv ;; j ++, str1 = NULL) (token = strtok_r (str1, argv, & saveptr1); si (token = = NULL) break; printf ("% d:% s \ n", j, token); for (str2 = token ;; str2 = NULL) (subtoken = strtok_r (str2, argv, & saveptr2); si (subtoken == NULL) break; printf ("->% s \ n", subtoken);)) exit (EXIT_SUCCESS);)

Otro ejemplo de un programa que usa strtok() puede encontrarse en getaddrinfo_a(3).