Menú
Está libre
registro
hogar  /  Internet/ Strtok s c descripción. Funciones para procesar cadenas

Descripción de Strtok s c. Funciones para procesar cadenas

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 siguiente 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 proporciona. 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

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 utilizado 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).

Los lenguajes de programación pueden incluir funciones especiales para trabajar con cadenas, eliminando así la necesidad de que un programador escriba sus propias funciones de procesamiento de cadenas. Por ejemplo, a menudo es necesario determinar la longitud de una cadena y, por lo tanto, los lenguajes proporcionan una función para medir su longitud.

En el lenguaje de programación C, las funciones para trabajar con cadenas se declaran en archivo de cabecera string.h, que debe recordar incluir en su código fuente. Hay unas veinte funciones para trabajar con cadenas. Entre ellos se encuentran los que buscan caracteres en una cadena, comparan funciones, copian cadenas, y también otras más específicas. Lista y descripción de la mayoría de los este momento en el lenguaje C, las funciones se pueden encontrar en el apéndice del libro de B. Kernighan, D. Ritchie "El lenguaje de programación C, segunda edición".

Todas las funciones declaradas en string.h en el curso de su trabajo pueden cambiar o no cambiar una de las cadenas pasadas por el puntero. Depende del propósito de la función. Sin embargo, la mayoría devuelve algo: un puntero a un carácter o un número entero. Además, si la función cambia uno de sus parámetros y fue llamada para esto, entonces lo que devuelve puede ignorarse (es decir, no asignarse a nada en la función de llamada).

Por ejemplo, la función strcpy () tiene esta declaración: char * strcpy (char *, const char *). Copia la cadena a la que apunta el segundo parámetro a la cadena a la que apunta el primer parámetro. Por tanto, se cambia el primer parámetro. Además, la función devuelve un puntero al primer carácter de la cadena:

char s1 [10], s2 [10]; char * s3; s3 = s2; obtiene (s1); s3 = strcpy (s2, s1); pone (s2); pone (s3); printf ("% p,% p \ n ", s2, s3);

Aquí s2 y s3 ​​apuntan al mismo carácter (printf () imprime las mismas direcciones). Sin embargo, lo que devuelve strcpy () no se puede asignar a una matriz. El resultado de esta función no suele asignarse a nada; a veces es suficiente que simplemente cambie una de las líneas pasadas por el puntero.

Otra cosa son funciones como strlen () o strcmp (), que no cambian los parámetros, pero se llaman por el bien del resultado. La función strcmp () compara dos cadenas de argumentos letra por letra (lexicográficamente) y devuelve 0, -1 o 1. Por ejemplo, llamar a strcmp ("boy", "body") devolverá 1, ya que el código de la letra "y" es mayor que la letra "d". Llamar a strcmp ("body", "boy") devolverá -1, ya que el primer argumento es lexicográficamente menor que el segundo.

Función Strtok ()

Con la función strtok (), puede dividir una cadena en partes separadas (tokens). La declaración de esta función se parece a este char * strtok (char *, const char *). Cuando se llama a la función por primera vez, la cadena que se va a dividir se especifica como primer parámetro. El segundo parámetro es la cadena de separación. En llamadas posteriores a la función para la misma cadena, el primer parámetro debe ser NULL, ya que la función ya ha "recordado" con qué está trabajando. Consideremos un ejemplo:

char str = "uno, dos, tres, cuatro, cinco"; char * sp; sp = strtok (str, ","); while (sp) (pone (sp); sp = strtok (NULL, ",");)

Como resultado de ejecutar este código, las palabras se muestran en una columna en la pantalla:

Uno dos tres CUATRO CINCO

En la primera llamada a strtok (), se pasa a la función un puntero al primer carácter de la matriz y una cadena de separación. Después de esta llamada, la matriz str se cambia, solo la palabra "uno" permanece en ella, y la función también devuelve un puntero a esta palabra, que se asigna a sp.

Aunque perdimos el resto de la matriz en la función de llamada, un puntero al resto de la matriz se almacena dentro de strtok (). Cuando se pasa NULL, la función "sabe" trabajar con esta cola.

Copiar partes de líneas

Cuando solo necesita concatenar dos cadenas, el problema se resuelve fácilmente llamando a la función strcat (), que agrega la segunda al final del primer argumento. Una función similar strncat () concatena los n caracteres de la segunda línea con la primera. n se especifica como tercer parámetro.

¿Y si la situación es más difícil? Por ejemplo, hay dos líneas no vacías y debe conectar el comienzo de la primera y el final de la segunda. Esto se puede hacer usando la función strcpy (), si pasa referencias a otros caracteres que no sean los primeros de las cadenas:

char s1 [20] = "Peter Smith", s2 = "Julia Roberts"; strcpy (s1 + 5, s2 + 5); pone (s1);

En este caso, la pantalla mostrará "Peter Roberts". ¿Por qué sucedió? Se pasó un puntero al sexto carácter de la primera línea a la función strcpy (). Esto llevó al hecho de que al copiar, los caracteres de esta línea se sobrescriben solo a partir del 6, ya que strcpy () no "sabe" nada sobre los caracteres anteriores. Solo una parte de la cadena también se pasa como segundo argumento, que se copia en el primero.

¿Cómo inserto una línea en medio de otra? Puede resolver este problema utilizando una tercera línea de "búfer", donde puede copiar primero la primera línea, luego la segunda, sobrescribiendo el final de la primera y luego agregando el final de la primera. Pero también puedes hacer esto:

char s1 [20] = "uno tres", s2 [20] = "dos"; strcpy (s2 + 3, s1 + 3); strcpy (s1 + 4, s2); pone (s1);

Aquí, primero, el final del primero se copia en la segunda línea, lo que da como resultado "dos tres". Luego, el segundo se copia a la primera línea, omitiendo su comienzo.

Descripción de algunas funciones para trabajar con cadenas

Ejercicio
A continuación se muestran descripciones de algunas de las funciones que realizan operaciones en cadenas. Diseñe y escriba pequeños programas que ilustren cómo funcionan estas funciones.

  • char * strchr (const char *, int c). Devuelve un puntero a la primera aparición de c en una cadena. Devuelve NULL si no hay tal carácter en la cadena.
  • char * strstr (const char * s2, const char * s1). Devuelve un puntero a la primera aparición de la cadena s1 en la cadena s2. Devuelve NULL si no hay coincidencia.
  • char * strncpy (char *, const char *, size_t n). Copia n caracteres de la segunda línea a la primera.
  • size_t strspn (carácter constante *, carácter constante *). Devuelve la longitud del comienzo de la primera línea, que incluye los caracteres que componen la segunda línea.

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 de 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 llamadas posteriores utilizan NULL como primer argumento. De esta forma 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;
}