Não existe asprintf() no Windows? Sem problemas!

Uma das funções bem úteis da glibc é asprintf() e sua irmã vasprintf(). Mas essas funções simplesmente não existem na implementação da glibc no MinGW! Elas também não existem na MSCRTxx.DLL, o runtime do seu programa compilado com o Visual Studio… Como implementá-la? É sempre bom ler a documentação das funções com cuidado… Se você ler o que as funções snprintf e vsnprintf retornam, verá que fica facílimo implementar as funções acima… Eis um pedaço do texto da especificação (ISO) dessas duas funções:

If  the output was truncated due to this limit then the return value is the number of characters (excluding the terminating null byte) which would have been written to the final string if enough space had been available

Ou seja, o valor de retorno é o número de caracteres que seriam impressos, se não houvesse um truncamento devido ao limite do tamanho da string… Assim, implementar o asprintf() fica tão simples como:

#include <stdio.h>
#include <malloc.h>
#include <stdarg.h>

/* Este protótipo funciona bem no GCC... deve ser 
   colocado num header file. O atributo faz com que o 
   compilador aplique as regras de verificação do printf na
   sua função! Retire o atributo, no caso do Visual Studio! */
int asprintf(char **, char *, ...) 
  __attribute__((printf,2,3));

/* Implementação */
int asprintf(char **s, char *fmt, ...)
{
  int size;
  char tmp[2];
  va_list argp;

  /* Tenta pegar o tamanho da string final. */
  va_start(argp, fmt);
  size = vsnprintf(tmp, 1, fmt, argp);
  if (size < 1)
  {
    *s = NULL;
    return -1;
  }
  va_end(argp);

  /* Aloca o espaço para a string final. */
  if ((*s = (char *)malloc(size+1)) == NULL)
    return -1;

  /* Finalmente, cria a string final. */
  va_start(argp, fmt);
  vsnprintf(*s, size+1, fmt, argp);
  va_end(argp);

  return size;
}
Anúncios

Deixe um comentário

Faça o login usando um destes métodos para comentar:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s