【发布时间】:2020-11-29 22:33:02
【问题描述】:
我正在尝试为链表的使用编写正确的控制台应用程序,因此我需要在无限循环中扫描多个命令并根据 switch case 选项执行某些操作。所以我为此使用scanf,但问题是当下一行不包含数字时,它会循环并开始打印甚至没有默认值。
`while(1)
{
printf("Enter a number of a command.\n");
scanf("%d",&command);
switch(command)
{
case -1:
....
default:
printf("Reenter command.\n");
break;
}
}
似乎当我读取无限量的数据堆栈时,它被重写了。我知道我必须限制阅读符号的数量,但不明白如何以正确的方式做到这一点。
在 Ubuntu 18.04.2 LTS 上使用 gcc 版本 5.4.0 (GCC)、c99
【问题讨论】:
-
我会先检查 scanf 的结果,然后再考虑它实际(假设)扫描过的内容,而不是盲目地假设它只是“有效”。它有一个记录的返回值是有原因的。或许先使用它,当事情变糟时,通过换行符或EOF(以先到者为准)丢弃输入流数据。
-
你要么想要一个
scanf模式来获取数字,但也保证它会占用换行符,或者,执行fgets[强制整行],然后使用sscanf缓冲。然后,如果它不是一个数字,则很容易重新循环 [无需处理类似:not_a_number 23] 的有趣行。您希望重新循环在第一行抛出任何 [bad] 并强制读取一个全新的行。IMO,fgets然后strtol是更好的选择。 -
当
scanf看到无法与当前使用的格式匹配的输入时,该输入未被读取。因此,在您的示例中,如果scanf无法将输入与您的格式匹配,则循环返回以使用相同格式重试不太可能产生不同的结果。 -
您刚刚发现为什么使用
scanf()读取输入是一个坏主意。使用fgets()或getline()之类的内容逐行读取输入,然后自己解析输入数据要可靠得多。至少这种方式意外输入不会像scanf()那样让您的输入流处于未知状态... -
您可能想阅读以下内容:A beginners' guide away from scanf()