Palavras-chave: C, arquivo texto, linhas, leitura, getline

Como dito num post anterior, a glibc possui uma função para ler linhas de comprimento arbitrário de um arquivo texto. Mas como esta função é especifica a glibc, alguns leitores pediram uma versão que faça o mesmo em qualquer sistema. Uma das muitas formas de fazer isto é:

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

char *pegalinha(FILE *f, char **buffer, size_t *buflen)
{
  char *ptr;
  char *tmp;
  int c;
  if (!*buffer || !*buflen)
  {
    *buflen= 32;
    *buffer= (char*)malloc(*buflen);
    if (!*buffer)
      return NULL;
  }

  ptr= *buffer;
  while ((c= fgetc(f)) != EOF) {
    *ptr++= c;
    if (c == '\\n') break;

    if (ptr - *buffer >= *buflen-1)
    {
      // aumenta o buffer um pouco mais
      tmp= (char*)realloc(*buffer, *buflen+32);
      if (!tmp)
        return NULL;
      // atualiza ptr para o caso do novo buffer estar em outro lugar
      ptr= tmp + (ptr - *buffer);
      *buflen+= 32;
      *buffer= tmp;
    }
  }
  *ptr= 0;
  return c==EOF ? NULL : *buffer;
}

int main(int argc, char **argv)
{
   FILE *file;
   char *linha= NULL;
   size_t tamlinha= 0;

   if (argc != 2) { printf("%s \\n", argv[0]); exit(1); }

   if (!(file= fopen(argv[1], "r"))) { perror(argv[1]); exit(1); }

   while (pegalinha(file, &linha, &tamlinha))
   {
     printf("%i:%s", tamlinha, linha);
   }
   if (linha)
     free(linha);
   fclose(file);
   return 0;
}