#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char buffer[10]; char *input = 0; size_t cur_len = 0; while (fgets(buffer, sizeof(buffer), stdin) != 0) { size_t buf_len = strlen(buffer); char *extra = realloc(input, buf_len + cur_len + 1); if (extra == 0) break; input = extra; strcpy(input + cur_len, buffer); cur_len += buf_len; } printf("%s [%d]", input, (int)strlen(input)); free(input); return 0; }
It's about a minimal set of changes that will give you a complete line of input. This increases the space to 9 bytes at a time; this is not the best way to do this, but there additional accounting includes performing the best methods (doubling the allocated space and keeping a record of how much money has been allocated versus how much is used). Note that cur_len
writes the length of the string in the space pointed to by input
, with the exception of the null terminal. Also note that using extra
avoids memory leaks when you are unable to allocate.
The strcpy()
operation can be legally replaced with memmove(input + cur_len, buffer, buf_len + 1)
(and in this context you can use memcpy()
instead of memmove()
, but it does not always work while memmove()
always works, therefore, it is more reliable to use memmove()
).
With doubling the length - the cur_max
variable records how much space is allocated, and cur_len
records how much space is used.
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(void) { char buffer[10]; char *input = 0; size_t cur_len = 0; size_t cur_max = 0; while (fgets(buffer, sizeof(buffer), stdin) != 0) { size_t buf_len = strlen(buffer); if (cur_len + buf_len + 1 > cur_max) { size_t new_len = cur_max * 2 + 1; if (buf_len + 1 > new_len) new_len = buf_len + 1; char *extra = realloc(input, new_len); if (extra == 0) break; input = extra; cur_max = new_len; } strcpy(input + cur_len, buffer); cur_len += buf_len; } printf("%s [%d]", input, (int)strlen(input)); free(input); return 0; }
source share