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

Otro alias

strtok

REVISAR

#incluir

char *strtok(char *calle, carácter constante *delimitar);
char *strtok_r(char *calle, carácter constante *delimitar, caracter **guardarptr);

Requisitos de macro de prueba de propiedad para glibc (ver función_prueba_macros(7)):

strtok_r(): _SVID_FUENTE || _BSD_FUENTE || _POSIX_C_FUENTE >= 1 || _XOPEN_FUENTE || _POSIX_FUENTE

DESCRIPCIÓN

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

en argumento delimitar establece un conjunto de bytes que se consideran separadores de tokens en la cadena analizada. La persona que llama puede especificar diferentes cadenas 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 cadena no incluye el byte delimitador. Si no hay más fichas, entonces strtok() devuelve NULL.

Secuencia de llamada strtok() que operan en una sola cadena mantiene un puntero que especifica 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 calle 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, entonces 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 encuentra mediante una búsqueda hacia adelante que dura hasta que se encuentra el byte delimitador o el byte nulo ("\0") de terminación. 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 comienzo del token encontrado.

De la descripción anterior se deduce que una secuencia de dos o más bytes delimitadores contiguos en una cadena escaneada se considera un delimitador único, y los bytes delimitadores al principio o al final de la cadena se ignoran. En otras palabras, las fichas devolvieron strtok() - siempre no líneas vacías. Es decir, por ejemplo, si hay una línea " aaa;;bbb,”, luego las llamadas posteriores strtok() con separadores de línea especificados " ;, ' devolvería las cadenas ' aaa" Y " bbb' seguido de un puntero nulo.

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

En primera llamada strtok_r() significado calle debe apuntar a la cadena analizada, y el valor guardarptr ignorado En llamadas posteriores, el valor calle debe ser NULL y el valor guardarptr no debe haber cambiado desde la llamada anterior.

Se pueden analizar varias cadenas al mismo tiempo en varias ejecuciones strtok_r() con diferentes argumentos guardarptr.

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 Significado
strtok() inocuidad en los hilosinseguro (MT-Carrera insegura: strtok)
strtok_r() inocuidad en los hilosinofensivo (MT-seguro)

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 precaución. Tenga en cuenta que: * Estas funciones cambian su primer argumento. * Estas funciones no se pueden usar con cadenas constantes. * Se pierde la identidad del byte delimitador. * Al analizar la función strtok() utiliza un búfer estático, por lo que no es seguro para subprocesos. Usar strtok_r() en este caso.

EJEMPLO

El siguiente programa 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 da la cadena a analizar. El segundo parámetro especifica los bytes delimitadores, que se utilizan para dividir la cadena en tokens "compuestos". El tercer parámetro especifica los bytes de separación que se utilizan 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); if (token = = NULL) break; printf("%d: %s\n", j, token); for (str2 = token; ; str2 = NULL) ( subtoken = strtok_r(str2, argv, &saveptr2); if (subtoken == NULL) break; printf(" --> %s\n", subtoken); ) ) exit(EXIT_SUCCESS); )

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

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

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 los delimitadores que definen el token. Si no hay token para devolver, se devuelve un puntero nulo.

En la versión C99, el calificador restrict se aplica a los parámetros str1 y str2.

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 esa cadena. En llamadas de función posteriores, se debe utilizar un puntero nulo como parámetro str1. En este caso, la cadena completa se actualizará en cada llamada de función.

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

La función strtok() proporciona un medio para reducir una cadena a sus partes constituyentes. Por ejemplo, el siguiente programa tokeniza la cadena "Uno, dos y tres".

#incluir #incluir int principal (vacío) char *p; p = strtok("Uno, dos y tres.", ","); imprimirf(p); do ( p = strtok(NULL, ",. "); if(p) printf("|%s", p); ) while(p), return 0; )

La salida de este programa es la siguiente.

uno | dos | y | tres

Observe cómo se llama primero a la función strtok() con la cadena original, pero las llamadas posteriores usan NULL como primer argumento. La función strtok() mantiene un puntero interno a la cadena que se va a procesar. Si el primer argumento de strtok() apunta a una cadena, el puntero interno se establece al principio de esa cadena. Si el primer argumento es igual al valor NULL, la función strtok() continúa procesando la línea anterior, comenzando desde la posición almacenada en el paso anterior, y avanza el puntero interno a medida que se recibe el siguiente token. Por lo tanto, la función strtok() "recorre" toda la cadena. Observe también cómo cambia la cadena delimitadora en la primera llamada a la función y en las subsiguientes. Los delimitadores se pueden definir de manera diferente en cada llamada.

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

Descripción:

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

La primera llamada a strtok() en realidad usa str1 como puntero. Las llamadas posteriores utilizan NULL como primer argumento. Por lo tanto, toda la cadena puede tokenizarse.

Es importante comprender que la función strtok() modifica la cadena a la que apunta str1. Cada vez que se encuentra un token, se coloca un carácter nulo en la ubicación donde se encontró el delimitador. Entonces strtok() avanza a lo largo de la cadena.

Con cada llamada 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 tokeniza la cadena "El soldado de verano, el patriota del sol" usando espacios y comas como delimitadores. Como resultado del programa se generará una línea de la siguiente forma: “La | verano | soldados | el | sol | patriota".
#incluir
#incluir
int principal (vacío)
{
char*p;
p = strtok( "El soldado de verano, el patriota del sol", " " ) ;
imprimirf(p);
hacer(
p=strtok(" \0 " , ", " ) ;
si (p) printf("|%s" , p) ;
) mientras (p);
devolver 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.

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