Accepting lines of input that are arbitrarily long is not something the C standard library was designed for. However, it can be an immensely useful feature to have. I recently came across this problem while rewriting the file input parts of libbitconvert. Here’s my solution, modeled after the C standard library’s fgets
:
int dynamic_fgets(char** buf, int* size, FILE* file) { char* offset; int old_size; if (!fgets(*buf, *size, file)) { return BCINT_EOF_FOUND; } if ((*buf)[strlen(*buf) - 1] == 'n') { return 0; } do { /* we haven't read the whole line so grow the buffer */ old_size = *size; *size *= 2; *buf = realloc(*buf, *size); if (NULL == *buf) { return BCERR_OUT_OF_MEMORY; } offset = &((*buf)[old_size - 1]); } while ( fgets(offset, old_size + 1, file) && offset[strlen(offset) - 1] != 'n' ); return 0; }
And here is an example of how to use it:
char* input; int input_size = 2; int rc; input = malloc(input_size); if (NULL == input) { return BCERR_OUT_OF_MEMORY; } rc = dynamic_fgets(&input, &input_size, stdin); if (BCERR_OUT_OF_MEMORY == rc) { return rc; } /* use input */ free(input);
To show you how dynamic_fgets
works, I’ll break into down line by line and then describe some of its features:
Continue reading ‘dynamic_fgets: Reading long input lines in C’