Search code examples
cbufferstdinfgets

Using fgets() without predefined buffer


I need to ask one more question about reading from the stdin. I am reading a huge trunk of lines from the stdin, but it is definitely unknown which is the size of every line. So I don't want to have a buffer like 50Mio just for a file having lines of three char and than a file using these 50 Mio per line. So at the moment I am having this code:

int cur_max = 2047;
char *str = malloc(sizeof(char) * cur_max);
int length = 0;

while(fgets(str, sizeof(str), stdin) != NULL) {
    //do something with str
    //for example printing
    printf("%s",str);
}

free(str);

So I am using fgets for every line and I do have a first size of 2047 char per line. My plan is to increase the size of the buffer (str) when a line hits the limit. So my idea is to count the size with length and if the current length is bigger than cur_max then I am doubling the cur_max. The idea comes from here Read line from file without knowing the line length I am currently not sure how to do this with fgets because I think fgets is not doing this char by char so I don't know the moment when to increase the size.


Solution

  • Incorrect code

    sizeof(str) is the size of a pointer, like 2, 4 or 8 bytes. Pass to fgets() the size of the memory pointed to by str. @Andrew Henle @Steve Summit

    char *str = malloc(sizeof(char) * cur_max);
    ...
    // while(fgets(str, sizeof(str), stdin) != NULL
    while(fgets(str, cur_max, stdin) != NULL
    

    Environmental limits

    Text files and fgets() are not the portable solution for reading excessively long lines.

    An implementation shall support text files with lines containing at least 254 characters, including the terminating new-line character. The value of the macro BUFSIZ shall be at least 256 C11 §7.21.2 9

    So once the line length exceeds BUFSIZ - 2, code is on its own as to if the C standard library functions can handle a text file.

    So either read the data as binary, use other libraries that insure the desired functionality, or rely on hope.

    Note: BUFSIZ defined in <stdio.h>