In general, avoid scanf
. It's very easy to leave yourself with unprocessed cruft on the input stream. Instead, read the whole line and then use sscanf
(or something else) to process it. This guarantees that you won't get stuck with a partially read line, those are hard to debug.
I prefer getline
to fgets
to read lines. fgets
requires you to guess how long the input might be, and input might get truncated. getline
will allocate the memory to read the line for you avoiding buffer overflow or truncation problems.
NOTE: getline
is it's not a C standard function, but a POSIX one and fairly recent (2008), though it was a GNU extension well before that. Some older compilers may not have it.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char c = '#';
char *line = NULL;
size_t linelen = 0;
/* First read the whole line */
while( getline(&line, &linelen, stdin) > 0 ) {
/* Then figure out what's in it */
long num = 0;
if( sscanf(line, "%ld", &num) > 0 ) {
for( int i = 0; i < num; i++ ) {
printf("%c", c);
}
printf("\n");
}
}
free(line);
return 0;
}
if( sscanf(line, "%ld", &num) > 0 ) {
will ignore any line that does not match any part of the pattern, such as a blank line or a line full of words, by checking how many things matched. Yet it will still handle 0
as a valid input.
$ ./test
foo
bar
foo123
12
############
1
#
0
2
##
I also moved num
inside the loop to guarantee it's reinitialized each iteration, and on the general principle of putting your variables in minimum scopes to avoid interference. And I upgraded it to a long int
better able to handle the unpredictably large numbers users might type in.