【问题标题】:Entering more characters skips prompts输入更多字符会跳过提示
【发布时间】:2014-09-24 14:19:27
【问题描述】:

我有一个缓冲区,假设为 10 个字符。我注意到当我输入 9 个字符时,它会跳过提示 EX。

Enter a p value:
123456789
Enter a q value:
Enter a k value:

但如果我输入 8 或更少,即使用户输入字母或特殊字符,它也会按照程序的预期正常接受。

我的代码:

#include <stdio.h>
#include <math.h>
#include <limits.h>
#include <ctype.h>
int main()
{
   char pbuffer[10], qbuffer[10], kbuffer[10];
   int p=0, q=0, k=0;
   int r, i, Q, c, count, sum;
   char a[3];
   a[0]='y';
   while(a[0]=='y' || a[0]=='Y')
   {
      printf("Enter a p value: \n");
      fgets(pbuffer, sizeof(pbuffer), stdin);
      p = strtol(pbuffer, (char **)NULL, 10);

      printf("Enter a q value: \n");
      fgets(qbuffer, sizeof(qbuffer), stdin);
      q = strtol(qbuffer, (char **)NULL, 10);

      printf("Enter a k value: \n");
      fgets(kbuffer, sizeof(kbuffer), stdin);
      k = strtol(kbuffer, (char **)NULL, 10);

      while(p<q+1)
      {
         Q=p;
         sum=0;
         count=0;
         while(Q>0)
         {
            count++;
            r = Q%10;
            sum = sum + pow(r,k);
            Q = Q/10;
         }

         if ( p == sum && i>1 && count==k )
         {
            printf("%d\n",p);

         }
         p++;
         a[0]='z';
      }
      while((a[0]!='y') && (a[0]!='Y') && (a[0]!='n') && (a[0]!='N'))
      {
         printf("Would you like to run again? (y/n) ");
         fgets(a, sizeof(a), stdin);
      }
   }
   return 0;
}

【问题讨论】:

标签: c input buffer stdin


【解决方案1】:

fgets 将读入尽可能多的字符,直到遇到换行符、EOF 或缓冲区大小。它还为以字符串结尾的\0 节省了一个额外的字符。因此,如果您输入 123456789\n 并有一个 10 个字符的缓冲区,fgets 知道它只能在该缓冲区中容纳 9 个字符,因此它会读取前 9 个字符并附加一个 NULL,从而为您提供 123456789\0你的缓冲区,\n 仍然在 STDIN 中。然后,您再次拨打fgets。它不等待输入,因为在 STDIN 中已经有一个 \n,所以它读取到 \n,恰好只有一个字符。因此,您的第二个缓冲区现在是 \n\0,而 STDIN 现在是空的。

要么使缓冲区足够大以存储要输入的字符串,要么在每个fgets 之后刷新 STDIN。可能是这样的:

while((c = getchar()) != '\n' && c != EOF)
/* Ignore the character */                ;

【讨论】:

  • 您能否推荐一下如何清除 STDIN 缓冲区。我尝试了很多方法,我看到工作的唯一方法是 fflush(stdin) 但我知道这不好用。
  • 真好!虽然现在,当我输入 8 个或更少的字符时,它会将我带到下一行,等待任何似乎具有零相关性的输入,然后提示我输入正确的输入。除了 9 个以上的字符可以正常工作的形式。
  • @AndrewRicci 啊,对,我没有意识到这一点。你可以做的是检查\n中是否有\n,如果没有则只执行上面的while循环。
  • 我很抱歉问这个问题,但是这在代码方面看起来如何。由于这是一个作业,我不相信编写我不理解的代码,我真的在尝试编写安全代码。
  • @AndrewRicci,if(pbuffer[9]=='\0'),清除stdin
【解决方案2】:

fgets之后添加这一行

scanf("\n");

【讨论】:

  • @CoolGuy 你找到我了!我打错了:)对不起!
【解决方案3】:

您可以使用 scanf(),而不是先读入 char 缓冲区,例如scanf("%d", &p) 可以同时替换 fgets() 和 strtol()。

【讨论】:

  • 我有 fgets 以防用户输入字母或输入太大。
【解决方案4】:

实际上,当提供给它的 size 参数小于输入的字符时,fgets 会保留 \n 字符。在您的情况下,您向 fgets 提供了值 10 作为大小。

所以当您输入 9 个字符时,它会用它们填充缓冲区并等待您输入停止读取。当你按下回车键时,它只是将空字符放在它的末尾并将回车键转发到下一个提示符,从而跳过它。

查看https://stackoverflow.com/a/11180652/1386897问题答案中的示例。

【讨论】:

    【解决方案5】:

    在调用fgets 之后刷新stdin 使用

    int c;
    while((c = getchar()) != '\n' && c != EOF);
    

    fgets 不等待用户输入数据的原因是因为fgets 知道缓冲区已满(\0 为 9 个字符和一个空格)并在最后附加一个\0字符串并将\n 留在stdin 中,由下一个fgets 采用

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-02
      相关资源
      最近更新 更多