Ventanas.  virus  Cuadernos.  Internet.  oficina.  Utilidades.  Conductores

#incluir char *strtok(char * str1, carácter constante * str2);

La función strtok() devuelve un puntero al siguiente token en la cadena a la que apunta el parámetro. str1. Los caracteres que componen la cadena direccionada por el parámetro. str2, son delimitadores que definen un token. Si no hay token para devolver, se devuelve un puntero nulo.

En la versión C99, los parámetros str1 Y str2 se aplicó el calificador de restricción.

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

Cada llamada a la función strtok() puede usar un conjunto diferente de delimitadores.

Ejemplo

Este programa divide la cadena "La hierba es verde, el sol brilla" en tokens separados por espacios y comas. el resultado será

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

Los lenguajes de programación pueden incluir funciones especiales para trabajar con cadenas, evitando así que el programador tenga que escribir sus propias funciones de procesamiento de cadenas. Por ejemplo, a menudo es necesario determinar la longitud de una cadena, por lo que 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 el archivo de encabezado string.h, que debe recordar incluir en su código fuente. Hay unas veinte funciones para trabajar con cadenas. Entre ellas se encuentran las que buscan caracteres en una cadena, funciones de comparación, copia de cadenas, así como otras más específicas. Relación y descripción de la mayoría de los existentes este momento en el lenguaje C, las funciones se pueden encontrar en el apéndice del libro de B. Kernighan, D. Ritchie "The C Programming Language. Second Edition".

Todas las funciones declaradas en string.h pueden o no modificar una de las cadenas pasadas por el puntero en el curso de su trabajo. Depende del propósito de la función. Sin embargo, la mayoría de ellos devuelven algo: ya sea 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 la siguiente 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. Entonces 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) ; imprimirf("%p, %p \norte", s2, s3) ;

Aquí s2 y s3 ​​apuntan al mismo carácter (printf() genera la misma dirección). Sin embargo, lo que devuelve strcpy() no se puede asignar a una matriz. El resultado de esta función no suele estar asignado a nada; a veces es suficiente que simplemente cambie una de las cadenas pasadas por el puntero.

Otra cosa son las funciones como strlen() o strcmp() , que no cambian los parámetros, pero se llaman por el resultado. La función strcmp() compara las dos cadenas de argumentos letra por letra (lexicográficamente) y devuelve 0, -1 o 1. Por ejemplo, llamar a strcmp("niño", "cuerpo") devolverá 1 porque código de letra "y" más que una carta"d". Llamar a strcmp("cuerpo", "niño") devolverá -1, porque el primer argumento es lexicográficamente menor que el segundo.

función strtok()

Usando la función strtok(), puede dividir una cadena en partes separadas (tokens). La declaración de esta función se ve así char *strtok (char *, const char *) . La primera vez que se llama a la función, el primer parámetro es la cadena a dividir. El segundo parámetro especifica la cadena delimitadora. En llamadas de función subsiguientes para la misma fila, el primer parámetro debe ser NULL, porque la función ya ha "recordado" con qué trabaja. Considere 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 siguientes palabras se muestran en una columna:

uno dos tres CUATRO CINCO

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

Aunque hemos perdido el resto de la matriz en la función de llamada, se conserva un puntero al resto de la matriz dentro de strtok(). Cuando se pasa NULL, la función "sabe" que debe trabajar con esa cola.

Copiar partes de cadenas

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

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

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

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

¿Cómo insertar una línea en medio de otra? Puede resolver este problema utilizando la tercera línea de "búfer", donde primero puede copiar la primera línea, luego la segunda, sobrescribir el final de la primera y luego adjuntar 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, resulta "dos tres". Luego, la segunda línea se copia a la primera línea, sin pasar por su comienzo.

Descripción de algunas funciones para trabajar con cadenas

Ejercicio
A continuación se encuentran descripciones de algunas funciones que realizan operaciones en cadenas. Diseñar y escribir pequeños programas que ilustren cómo funcionan estas funciones.

  • char *strchr (const char *, int c) . Devuelve un puntero a la primera aparición del carácter c en la cadena. Devuelve NULL si no existe 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. Si no hay coincidencias, devuelve NULL.
  • char *strncpy (char *, const char *, size_t n) . Copia n caracteres de la segunda cadena a la primera.
  • size_t strspn (const char *, const char *) . Devuelve la longitud del principio de la primera cadena que incluye los caracteres que componen la segunda cadena.

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

Valor de retorno:

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 extrae la siguiente parte de la cadena a la que apunta el argumento str, separada por uno de los caracteres delimitadores especificados en la cadena a la que apunta el argumento sep. Una llamada sucesiva 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 una cadena que se va a separar (str) y el comienzo de una cadena que contiene delimitadores (sep). En primer lugar función de carrera itera a través de los caracteres de la cadena str uno por uno y busca un carácter que no esté contenido en la cadena delimitadora sep. Si en la cadena str se encuentra el carácter de fin de línea antes de encontrar un carácter no incluido en la cadena sep, entonces la cadena str no se puede dividir en partes y se devuelve un puntero nulo (NULL). Si se encuentra tal carácter, se considera que es el comienzo de la primera parte de str."

A continuación, la función strtok busca el delimitador, es decir, el carácter incluido en la cadena sep. Si no se encuentra dicho carácter, la cadena str se considera una parte y las subsiguientes divisiones de la cadena str devolverán un puntero nulo. Si se encuentra tal carácter. luego se reemplaza con un carácter nulo (el 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 que se va a dividir, se especifica NULL como el primer aumento. En este caso, la función strtok continuará dividiéndose desde la dirección recordada. El algoritmo de partición seguirá siendo el mismo.

Ejemplo:

En el ejemplo, la cadena "test1/test2/test3/test4" se divide en partes en el delimitador "/" mediante la función strtok. El resultado de la división se imprime en la consola.

Resultado:

Salida de la consola:


4 respuestas

Dos cosas que debe saber sobre strtok. Como se mencionó, "mantiene el estado interno". Además, él arruinó la línea que le das de comer. Esencialmente, escribirá "\ 0" donde encontrará el marcador que proporcionó y devolverá 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í.

Una consecuencia importante es que no puede usar strtok en una cadena como const char* "hello world"; , ya que obtendrá una infracción de acceso al cambiar el contenido de una cadena const char*.

Lo "bueno" de strtok es que en realidad no copia cadenas, por lo que no tiene que administrar la asignación de memoria adicional, etc. Pero si no entiende lo anterior, tendrá problemas para usarlo.

Ejemplo. Si tiene "esto, es, cadena", las llamadas sucesivas a strtok generarán punteros de la siguiente manera (el valor ^ es el valor de retorno). Tenga en cuenta que se agrega "\0" donde se encuentran los tokens; esto significa que se cambia la línea original:

E s , i s , a , s t r i n g \0 esto, es, una, cadena 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 cuerda ^

Espero que esto tenga sentido.

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

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

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

Debido a la forma en que funciona strtok, debe asegurarse de que está vinculando a la versión de subprocesos múltiples del tiempo de ejecución de C si está escribiendo una aplicación de subprocesos múltiples. Esto asegura que cada subproceso obtenga 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 seguridad de subprocesos, debe usar strtok_r

Echa un vistazo a static char *last;

Char * strtok(s, delim) registro 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 (busca 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; hacer ( if ((sc = *spanp++) == c) ( if (c == 0) s = NULL; else s[-1] = 0; last = s; return (tok); ) ) while (sc != 0); ) /* NO ALCANZADO */ )

compartir

1) Encuentra el siguiente token en la cadena de bytes terminada en cero a la que apunta str . Los caracteres delimitadores se identifican mediante la cadena de bytes nulos a la que apunta delim .

Esta función se llama multiplicación múltiple para obtener tokens consecutivos de la misma cadena.

  • Si str! = cadena NULL! = NULL , la llamada se trata como la primera llamada a strtok para esa fila en particular. La función busca el primer carácter que No contenido en delim.
  • Si no se encontró dicho símbolo, entonces no hay tokens en él y la función devuelve un puntero nulo.
  • Si tal carácter fue encontrado, será inicio simbólico. Luego, la función busca desde ese punto el primer carácter contenido en delim .
    • Si no se encuentra dicho carácter, str tiene solo un token y las llamadas futuras a strtok devuelven un puntero nulo
    • Si se encuentra tal carácter, es remplazado el carácter nulo "\0" y el puntero al siguiente carácter se almacenan en una ubicación estática para llamadas posteriores.
  • Luego, la función devuelve un puntero al comienzo del token.
  • Si str == NULL , la llamada se trata como llamadas posteriores a strtok: la función continúa desde donde se quedó en la llamada anterior. El comportamiento es el mismo que si el puntero previamente almacenado se pasara como str .

El comportamiento no está definido a menos que str o delim sea un puntero a una cadena de bytes terminada en nulo.

2) Igual que (1) excepto que cada paso escribe el número de caracteres que quedan para buscar en str en *strmax y escribe el estado interno del tokenizador en *ptr. Las llamadas repetidas (con strmax nulo) deben pasar strmax y ptr con los valores almacenados por la llamada anterior. Además, en tiempo de ejecución, los siguientes errores y el actual se llama establecer función controlador de restricciones sin almacenar nada en el objeto señalado por ptr

  • strmax , delim o ptr - puntero nulo
  • en una llamada no inicial (con una cadena nula), *ptr es un puntero nulo
  • en la primera llamada, *strmax es cero o mayor que RSIZE_MAX
  • el final de la búsqueda de tokens llega al final de la cadena original (según lo medido por el valor inicial de *strmax) sin encontrar un terminador nulo

El comportamiento no está definido si str apunta a una matriz de caracteres que no tiene un carácter nulo y strmax apunta a un valor que es mayor que el tamaño de esa matriz de caracteres. Al igual que todas las funciones relacionadas con la verificación de límites, solo se garantiza que strtok_s esté disponible si __STDC_LIB_EXT1__ está definido por la implementación y si el usuario define __STDC_WANT_LIB_EXT1__ para la constante entera 1 antes de incluir string.h .

opciones

Valor de retorno

Devuelve un puntero al comienzo del siguiente token o NULL si no hay más tokens.

La nota

Esta función es destructiva: escribe los caracteres "\0" en los elementos de la cadena str. En particular, un literal de cadena no se puede usar como primer argumento para strtok .

Cada llamada a strtok modifica una variable estática: no es seguro para subprocesos.

A diferencia de la mayoría de los tokenizadores, los delimitadores en strtok pueden ser diferentes para cada token sucesivo e incluso pueden depender del contenido de los tokens anteriores.

La función strtok_s se diferencia de la función POSIX strtok_r al almacenarla fuera de la cadena tokenizada y verificar los límites de tiempo de ejecución.

ejemplo

#definir __STDC_WANT_LIB_EXT1__ 1 #incluir #incluir int main(void) ( char input = "Un pájaro bajó por el camino"; printf("Análisis de la cadena de entrada "%s"\n", input); char *token = strtok(input, " "); while( token) ( puts(token); token = strtok(NULL, " "); ) printf("Contenido de la cadena de entrada ahora: ""); for(size_t n = 0; n< sizeof input; ++n) input[n] ? printf("%c", input[n]) : printf("\\0"); puts("""); #ifdef __STDC_LIB_EXT1__ char str = "A bird came down the walk"; rsize_t strmax = sizeof str; const char *delim = " "; char *next_token; printf("Parsing the input string "%s"\n", str); token = strtok_s(str, &strmax, delim, &next_token); while(token) { puts(token); token = strtok_s(NULL, &strmax, delim, &next_token); } printf("Contents of the input string now: ""); for(size_t n = 0; n < sizeof str; ++n) str[n] ? printf("%c", str[n]) : printf("\\0"); puts("""); #endif }

Salida posible:

Analizando la cadena de entrada "Un pájaro bajó por el paseo" Un pájaro bajó por el paseo Contenido de la cadena de entrada ahora: "Un\0pájaro\0caminó\0por\0el\0paseo\0" Analizando la cadena de entrada "Un pájaro bajó por el caminar" Un pájaro bajó por el paseo Contenido de la cadena de entrada ahora: "Un\0pájaro\0caminó\0por\0el\0paseo\0"

  • C11 (ISO/CEI 9899:2011):
    • 7.24.5.8 La función strtok (p: 369-370)
    • K.3.7.3.1 Función strtok_s (p: 620-621)
  • C99 (ISO/CEI 9899:1999):
    • 7.21.5.8 La función strtok (p: 332-333)
  • C89/C90 (ISO/CEI 9899:1990):
    • 4.11.5.8 función strtok
encuentra la primera ubicación de cualquier carácter en una cadena, en otra cadena
(función)

solo caracteres que no se encuentran en otra cadena de bytes
(función)
devuelve la longitud del segmento inicial máximo, que consta de
solo caracteres encontrados en otra cadena de bytes
(función)

(C95) (C11)

encuentra el siguiente token en una cadena ancha
(función)
Documentación de C++ para strtok

Si nota un error, seleccione un fragmento de texto y presione Ctrl + Enter
COMPARTIR: