You really should use getline for this. You could use scanf with something like:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
int rv;
FILE *fp = stdin;
char *line = NULL;
while( (rv = fscanf(fp, "%m[^\n]", &line)) != EOF ){
if( rv == 0 ){
line = "";
}
puts(line);
fgetc(fp); /* Consume newline */
if( rv ){
free(line);
}
}
return 0;
}
But, don't. getline is more widely available than %m, and easier to understand. The %m specifier is a non-standard extension that allocates space for the data, and the caller is responsible for freeing that data. getline is a posix extension that does exactly what you're trying to do (allocates space for a buffer to read a full line of text.)
Also, note that the conversion specifier is just [, not s, and the format string should not have the trailing s.
To use getline, you can do:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
FILE *fp = stdin;
char *line = NULL;
size_t cap = 0;
while( getline(&line, &cap, fp) != -1 ){
fputs(line, stdout);
}
free(line);
return 0;
}
Note that when using getline, the newline stays in the buffer, while the scanf method does not add that character. Another advantage of getline is that you only need to free the buffer once, and it will minimize the allocations.