这类问题可能看起来像是一个令人讨厌的问题,但我宁愿请你详细解释为了满足我的好奇心。
我们假设我们有以下代码:
#include <stdio.h>
int main(void)
{
char ch;
scanf("%c", &ch);
printf("%d\n", ch);
return 0;
}
编译完成后,可以使用CTRL + Z快捷键在行模拟EOF的开头键入,然后按ENTER键 - 这样做两次。
输出如下:
^ Z
^ Z
-52
按任意键继续 。 。
1)现在发生了什么?
我对这种循环有另一个疑问:
while (scanf("%c", &ch) != EOF)
printf("%c\n", ch);
printf("BYE!\n");
输出将是:
^ Z
^ Z
BYE!
按任意键继续 。 。 。
2)为什么在第一次EOF模拟后它不会终止?
编辑:我搜索了有关我的疑问的SO的另一个答案,我认为很难使用scanf()
,因为它有更好的替代品,如fgets()
或fread()
。请看下面的另一个例子:
int input;
char ch;
while (scanf("%d", &input) != 1) //checking for bad input
while ((ch = getchar()) != '\n') //disposing of bad input
putchar(ch);
printf("BYE!\n");
我在行的开头输入了五次 CTRL + Z ,输出将变为:
^ Z
^ Z
^ Z
^ Z
^ Z
^ Z
^ Z
^ Z
^ Z
^ Z
^ CP按任意键继续。 。 。
我添加了五个EOF并且必须在最后一行用 CTRL + C 杀死程序。
3)为什么空间出现在第5行并且在末尾可见(有时两个空格在'^ CP持续任何键继续...'之前)?
最后一个例子是从上面修改循环(代码中没有意义):
while (scanf("%d", &input) != EOF);
printf("BYE!\n");
输出是:
^ Z
^ Z
^ Z
BYE!
按任意键继续 。 。 。
4)为什么我们使用三次 CTRL + Z 而不是两次,因为它是在上面的评论中写的?
答案 0 :(得分:0)
您的代码调用未定义的行为。如果scanf()
无法读取格式字符串"%c"
的字节,则会返回EOF
并使ch
保持未初始化状态。
最好以这种方式编写代码:
while (scanf("%c", &ch) == 1)
printf("%c\n", ch);
printf("BYE!\n");