While trying to get newline character as input using scanf and display it as output as this discussion suggests, I tried the following code,
#include <stdio.h>
void main()
{
int n;
printf("Loop:\n");
scanf("%d",&n);
for (int i = 0; i < n; i)
{
char in[28];
scanf("'[^\n]%*c",&in);
printf("%s\n",in);
}
}
During execution, inside the for loop the input stream doesn't accept any inputs and instead displays n smiley faces. Is this because of the trailing newline character after reading n?
CodePudding user response:
Beyond the type mismatch, the reason scanf("'[^\n]%*c",&in);
does not read extra input from the user is there is a pending newline left by scanf("%d",&n);
. scanf()
fails because there is no match for the character set and the newline is not consumed by %*c
because the previous mismatch stops the scan.
Here is a modified version:
#include <stdio.h>
int flush_input(void) {
int c;
while ((c = getchar()) != EOF && c != '\n')
continue;
return c;
}
int main() {
int n;
printf("Loop:\n");
if (scanf("%d", &n) != 1)
return 1;
flush_input();
for (int i = 0; i < n; i) {
char in[28];
if (scanf("'[^\n]", in) != 1) {
// blank line or EOF
*in = '\0';
}
printf("%s\n", in);
if (flush_input() == EOF)
break;
}
return 0;
}
CodePudding user response:
How to compile any C program as a beginner: What compiler options are recommended for beginners learning C?
Following this advise and compiling with gcc gives 2 problems:
<source>:2:6: error: return type of 'main' is not 'int' [-Wmain]
2 | void main()
| ^~~~
<source>: In function 'main':
<source>:11:21: error: format '%[^
' expects argument of type 'char *', but argument 2 has type 'char (*)[28]' [-Werror=format=]
11 | scanf("'[^\n]%*c",&in);
| ~~~~~^~ ~~~
| | |
| char * char (*)[28]
The first reported error is because
void main()
is an implementation-defined form of main() which isn't suitable for gcc unless you explicitly compile for embedded systems or the like. Switch toint main (void)
.The second reported error says that the conversion
%c
expected a parameter of typechar*
. You gave it a parameter of typechar (*)[28]
. Huh, what is that? Well, it is a pointer to an array of 28 char. Not the same thing and not what you want, but what you get if you do&in
instead ofin
.
Luckily, viewing multiple lines of the gcc output gives you the exact location of the bug, after which you will find the bug in seconds:
11 | scanf("'[^\n]%*c",&in);
| ~~~~~^~ ~~~
| | |
| expect BUG HERE FIX ME
Now if you follow the above guidelines, you should be able fix the next trivial bug that the compiler has already found.