quarta-feira, 27 de outubro de 2010

How to read an unknown lenght line to a string in C

/*===========================*
 *    Reading dinamically    *
 *===========================*/
#include <stdio.h>
#include <stdlib.h>

#define DATALEN BUFSIZ 

struct block {
    char data[DATALEN];
    struct block *next;
};

struct block *
alloc_block (void)
{
    struct block *new = malloc (sizeof (struct block));
    if (!new) {
        perror ("malloc");
        exit (EXIT_FAILURE);
    }
    return new;
}

int
readfrom (char **str, FILE *stream, int finalchar)
{
    struct block *first;
    struct block *ptr;
    struct block *prev;
    struct block *tmp;
    int ch, indx = 0, nblocks = 1, strindx;

    first = ptr = alloc_block();
    ptr->next = NULL;
    /* read and alloc string as a linked list */
    while ((ch = getc(stream)) != finalchar) {
        if (indx == DATALEN) {
            tmp = alloc_block ();
            indx = 0; 
            nblocks++;
            tmp->next = NULL;
            ptr->next = tmp;
            ptr = tmp;
        } else if (indx > DATALEN) {
            fprintf (stderr, "readline error: Index error\n");
            exit (EXIT_FAILURE);
        }
        ptr->data[indx++] = ch;
    }
    ptr->data[indx] = '\0';
    *str = malloc ( (nblocks - 1) * DATALEN + indx );    
    /* run in list freeing it */
    for 
    (ptr = first, strindx = 0; 
     ptr != NULL; 
     prev = ptr, ptr = ptr->next, free (prev)) 
    {
        for 
        (indx = 0; 
         indx < DATALEN && ptr->data[indx] != '\0'; 
         indx++, strindx++) 
        {
            (*str)[strindx] = ptr->data[indx]; 
        }
    }
    (*str)[strindx] = '\0';
    return strindx;
}

        
int
main (void)
{
    char *str;
    int len;
    len = readfrom (&str, stdin, '\n');
    printf ("Your string with len %d is `%s'\n", len, str);
    return 0;
}

Um comentário: