【问题标题】:Overflow with scanf, even using fflush and input length limitation [duplicate]使用scanf溢出,即使使用fflush和输入长度限制[重复]
【发布时间】:2021-12-16 21:07:50
【问题描述】:

我是 C 的初学者,目前正在阅读 Prinz 先生的《C: Einfuehrung undprofessionalelle Anwendung》一书。下面书中的示例应该显示如何使用 scanf 限制输入并在其间刷新缓冲区以获得新输入。

在这两种情况下,我都输入“123123123123”作为银行帐号。如果我在第 11 行退出,那么 printf 会验证是否只存储了前 8 个符号。如果我没有在第 11 行退出,那么剩余的符号将被写入“货币”字段,并且程序不会要求第二次输入。

我查看了手册页并知道本地是在堆栈上分配的。但我仍然不明白为什么会发生溢出,或者为什么书中的例子对我不起作用。你能向初学者解释一下吗?

Here 有人说fflush(stdin) 也是一个编码错误。如果是这样,你能解释一下为什么这本书会出现吗? :)

1. # include <stdio.h>
2. 
3. int main() {
4.     long bank_account;
5.     double money;
6. 
7.     printf("\nEnter your bank account: ");
8.     scanf("%8ld", &bank_account);
9.     printf("Bank account: %d, Amount: %.3f\n", bank_account, money);
10.     
11.     // <- here
12.    fflush(stdin);
13.    
14.    printf("\nHow much money to hold: ");
15.    scanf("%lf", &money);
16.    printf("Bank account: %d, Amount: %.3f\n", bank_account, money);
17.
18.    return 0;
19. }

【问题讨论】:

  • 这不是溢出,只是剩余的符号仍在缓冲区中。解决方案见stackoverflow.com/a/49265365/1871033。
  • 请下次贴出不带行号的代码。
  • 我建议您不要在帐户、电话、卡、门牌等号码中使用整数。使用字符串。如果输入的帐号长于 8,请不要截断它(就像您的 scanf 用法那样),而是将其标记为不正确的输入,而不向用户提供任何线索。
  • 至于为什么书中教了不正确的 fflush:它显然不是最好的书,而且似乎它教的东西恰好在作者的平台上有效但不能普遍适用(如您发现了 - 它不适用于 yours)
  • fflush(stdin) 在早期的编译器版本中受 Windows 支持,但现在不支持。

标签: c scanf overflow fflush


【解决方案1】:

您的银行帐户是 long 类型 - 所以您的 printf 应该使用 %ld 代替:

printf("Bank account: %ld, Amount: %.3f\n", bank_account, money);

【讨论】:

  • 也许值得注意的是编译器应该对此发出警告。
猜你喜欢
  • 2015-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-03-10
  • 2021-06-19
  • 1970-01-01
  • 2014-04-09
  • 1970-01-01
相关资源
最近更新 更多