[英]Why doesn't scanf with character set format read input in a for loop?
While trying to get newline character as input using scanf and display it as output as this discussion suggests, I tried the following code,在尝试使用 scanf 获取换行符作为输入并将其显示为此讨论所建议的输出时,我尝试了以下代码,
#include <stdio.h>
void main()
{
int n;
printf("Loop:\n");
scanf("%d",&n);
for (int i = 0; i < n; ++i)
{
char in[28];
scanf("%27[^\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.在执行期间,在 for 循环内,输入流不接受任何输入,而是显示 n 个笑脸。 Is this because of the trailing newline character after reading n?
这是因为读取 n 后尾随换行符吗?
Beyond the type mismatch, the reason scanf("%27[^\n]%*c",&in);
除了类型不匹配,原因
scanf("%27[^\n]%*c",&in);
does not read extra input from the user is there is a pending newline left by scanf("%d",&n);
不读取用户的额外输入是否存在
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. scanf()
失败,因为没有匹配字符集并且换行符没有被%*c
消耗,因为之前的不匹配停止了扫描。
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("%27[^\n]", in) != 1) {
// blank line or EOF
*in = '\0';
}
printf("%s\n", in);
if (flush_input() == EOF)
break;
}
return 0;
}
How to compile any C program as a beginner: What compiler options are recommended for beginners learning C?如何作为初学者编译任何 C 程序:对于学习 C 的初学者,推荐哪些编译器选项?
Following this advise and compiling with gcc gives 2 problems:遵循此建议并使用 gcc 进行编译会出现 2 个问题:
<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("%27[^\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.第一个报告的错误是因为
void main()
是 main() 的实现定义形式,它不适合 gcc,除非您为嵌入式系统等显式编译。 Switch to int main (void)
.切换到
int main (void)
。
The second reported error says that the conversion %c
expected a parameter of type char*
.第二个报告的错误表示转换
%c
需要一个char*
类型的参数。 You gave it a parameter of type char (*)[28]
.你给了它一个
char (*)[28]
类型的参数。 Huh, what is that?咦,那是什么? Well, it is a pointer to an array of 28 char.
嗯,它是一个指向 28 个字符的数组的指针。 Not the same thing and not what you want, but what you get if you do
&in
instead of in
.不是同一件事,也不是你想要的,而是如果你做
&in
而不是in
,你会得到什么。
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:幸运的是,查看多行 gcc 输出可以为您提供错误的确切位置,之后您将在几秒钟内找到错误:
11 | scanf("%27[^\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.现在,如果您遵循上述指南,您应该能够修复编译器已经发现的下一个小错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.