Pregunta

Cómo analizar la seguridad de la cadena tabuladores delimitador? por ejemplo: test \ TBLA-bla-bla \ t2332?

¿Fue útil?

Solución

strtok() es una función estándar para analizar cadenas con delimitadores arbitrarios. Es, sin embargo, no seguro para subprocesos. Su biblioteca C de elección podría tener una variante flujos seguros.

Otra forma compatible con el estándar (acaba de escribir esto, es no ensayado ):

#include <string.h>
#include <stdio.h>

int main()
{
    char string[] = "foo\tbar\tbaz";
    char * start = string;
    char * end;
    while ( ( end = strchr( start, '\t' ) ) != NULL )
    {
        // %s prints a number of characters, * takes number from stack
        // (your token is not zero-terminated!)
        printf( "%.*s\n", end - start, start );
        start = end + 1;
    }
    // start points to last token, zero-terminated
    printf( "%s", start );
    return 0;
}

Otros consejos

Uso strtok_r en lugar de strtok (si está disponible). Tiene uso similar, excepto que es reentrante, y no modificar la cadena como strtok hace. [ Editar En realidad, me equivoqué. Como señala Christoph, strtok_r reemplaza por los delimitadores '\ 0'. Por lo tanto, debe operar en una copia de la cadena si desea conservar la cadena original. Pero es preferible strtok porque es reentrante y segura hilo]

strtok dejará su cadena original modificado. Sustituye el delimitador con '\ 0'. Y si la cadena pasa a ser una constante, almacenado en una memoria de sólo lectura (algunos compiladores lo harán), en realidad se puede obtener una violación de acceso.

Uso strtok() de string.h.

#include <stdio.h>
#include <string.h>

int main ()
{
    char str[] = "test\tbla-bla-bla\t2332";
    char * pch;
    pch = strtok (str," \t");
    while (pch != NULL)
    {
        printf ("%s\n",pch);
        pch = strtok (NULL, " \t");
    }
    return 0;
}

Se puede utilizar cualquier biblioteca de expresiones regulares o incluso el GScanner GLib, consulte aquí y aquí para obtener más información.

Sin embargo, otra versión; éste separa la lógica en una nueva función

#include <stdio.h>

static _Bool next_token(const char **start, const char **end)
{
    if(!*end) *end = *start;    // first call
    else if(!**end)             // check for terminating zero
        return 0;
    else *start = ++*end;       // skip tab

    // advance to terminating zero or next tab
    while(**end && **end != '\t')
        ++*end;

    return 1;
}

int main(void)
{
    const char *string = "foo\tbar\tbaz";

    const char *start = string;
    const char *end = NULL; // NULL value indicates first call

    while(next_token(&start, &end))
    {
        // print substring [start,end[
        printf("%.*s\n", end - start, start);
    }

    return 0;
}

Si necesita una forma segura binario a tokenize una cadena dada:

#include <string.h>
#include <stdio.h>

void tokenize(const char *str, const char delim, const size_t size)
{
        const char *start = str, *next;
        const char *end = str + size;

        while (start < end) {
                if ((next = memchr(start, delim, end - start)) == NULL) {
                        next = end;
                }

                printf("%.*s\n", next - start, start);
                start = next + 1;
        }
}

int main(void)
{
        char str[] = "test\tbla-bla-bla\t2332";
        int len = strlen(str);

        tokenize(str, '\t', len);

        return 0;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top