I think this should work. It's not the most optimal way because of constant reallocs and possible wasted space, but it works and is dynamic. Don't forget to check the return value of fgets() for errors.
const unsigned int CHUNK_SIZE = 16; // whatever you want here
char *string = NULL;
int length = 0;
bool done = false;
while (!done) {
printf("Enter a string: ");
if (realloc(string, length+CHUNK_SIZE))
fscanf(string[length], CHUNK_SIZE, stdin);
else {
fprintf(stderr, "Out of memory!\n");
break;
}
length += strlen(string[length]);
if (string[length-1] == '\n') {
string[length-1] = '\0';
done = true;
}
}