Search code examples
cmallocrealloc

Using fgets with realloc()


I'm trying to create a function to read a single line from a file of text using fgets() and store it in a dynamically allocating char* using malloc()but I am unsure as to how to use realloc() since I do not know the length of this single line of text and do not want to just guess a magic number for the maximum size that this line could possibly be.

#include "stdio.h"
#include "stdlib.h"
#define INIT_SIZE 50

void get_line (char* filename)

    char* text;
    FILE* file = fopen(filename,"r");

    text = malloc(sizeof(char) * INIT_SIZE);

    fgets(text, INIT_SIZE, file);

    //How do I realloc memory here if the text array is full but fgets
    //has not reach an EOF or \n yet.

    printf(The text was %s\n", text);

    free(text);

int main(int argc, char *argv[]) {
    get_line(argv[1]);
}

I am planning on doing other things with the line of text but for sake of keeping this simple, I have just printed it and then freed the memory.

Also: The main function is initiated by using the filename as the first command line argument.


Solution

  • The getline function is what you looking for.

    Use it like this:

    char *line = NULL;
    size_t n;
    getline(&line, &n, stdin);
    

    If you really want to implement this function yourself, you can write something like this:

    #include <stdlib.h>
    #include <stdio.h>
    
    char *get_line()
    {
        int c;
        /* what is the buffer current size? */
        size_t size = 5;
        /* How much is the buffer filled? */
        size_t read_size = 0;
        /* firs allocation, its result should be tested... */
        char *line = malloc(size);
        if (!line) 
        {
            perror("malloc");
            return line;
        }
    
        line[0] = '\0';
    
        c = fgetc(stdin);
        while (c != EOF && c!= '\n')
        {            
            line[read_size] = c;            
            ++read_size;
            if (read_size == size)
            {
                size += 5;
                char *test = realloc(line, size);
                if (!test)
                {
                    perror("realloc");
                    return line;
                }
                line = test;
            }
            c = fgetc(stdin);
        }
        line[read_size] = '\0';
        return line;
    }