Dica valiosa: Obtendo tokens em threads e tratadores de sinais

Também já escrevi sobre isso por aqui… A função padrão para obter tokens de strings com separadores conhecidos, strtok, não é thread safe e nem mesmo é segura para ser usada em tratadores de sinais (assynchronous signal unsafe). Para tais recursos existe a função strtok_r, que é reentrante. Mas, a dificuldade imposta por strtok_r é que ela exige uma string extra, onde o estado atual é mantido. O protótipo é:

char *strok_r(char *str, const char *delims, char **state);

Além desse ponteiro state, a função funciona como a strtok original.

Mas, se você tem certeza que vai usar o GCC, a glibc disponibiliza outra função, um wrapper sobre strtok_r, chamada strsep, cujo protótipo é:

char *strsep(char **str, const char *delims);

Ela é bem mais simples: O ponteiro str aponta para o ponteiro que contém a string. Ele deve ser um ponteiro independente porque será atualizado a cada chamada a strsep. A função devolve o token ou NULL, se não achar nenhum ou se já estiver no final da string. A cada chamada de strsep o ponteiro str será atualizado para apontar para a posição após um separador:

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

void main(void)
{
  char s[] = "A,B,C.D";
  char *p = s;
  char *q;

  while ((q = strsep(&p, ".,")) != NULL)
  {
    printf("Token=\"%s\", Substring=", q);
    if (!p)
      puts("NULL");
    else
      printf("\"%s\"\n", p);
  }
}

E o resultado:

$ gcc -o test test.c
$ ./test
Token="A", Substring="B,C.D"
Token="B", Substring="C.D"
Token="C", Substring="D"
Token="D", Substring=NULL
Anúncios