【问题标题】:fflush() is not working in Linuxfflush() 在 Linux 中不起作用
【发布时间】:2013-06-26 11:33:51
【问题描述】:

我在 Linux GCC 中使用了 fflush(),但它不起作用。该功能有其他选择吗?这是我的代码:

#include<stdio.h>
void main()
{
  char ch='y';
  while(ch=='y')
  {
    int a;
    printf("Enter some value:");
    scanf("%d",&a);
    fflush(stdin);
    printf("Do you want to continue?");
    scanf("%c",&ch)
  }

我得到的输出是:

Enter some value: 10

然后程序结束。就这样。我可以在 Linux 中做什么?有替代功能吗?

【问题讨论】:

  • 请记住,刷新stdin 实际上是未定义的行为。不要这样做。
  • 不要fflush(stdin)。而是将scanf() 更改为fgets()
  • @Stefan 我只是尝试使用 fflush() 刷新输入流。在windows下可以,但是在linux下就不行了……
  • @sundar 是的,但是为什么要刷新输入流?除非您说出您需要程序做什么,否则不可能推荐替代方案。
  • fflush() 是对输入流的未定义操作。一些编译器可能会作为扩展提供对这种未定义行为的支持。我不建议依赖这个。

标签: c linux gcc


【解决方案1】:

不要使用 fflush,改用这个函数:

#include <stdio.h>
void clean_stdin(void)
{
    int c;
    do {
        c = getchar();
    } while (c != '\n' && c != EOF);
}

fflush(stdin) 取决于实现,但此功能始终有效。在 C 中,使用 fflush(stdin) 被认为是不好的做法。

【讨论】:

  • fflush(stdin) 是一种不好的做法,而不是fflush。 ;)
  • @md5 “不是 fflush” 是什么意思。你的意思是 fflush 是好习惯吗?还是没有参数的 fflush 不存在?
  • @barlop: fflush 可能有用,例如使用输出流:fflush(stdout) 强制写入输出(请参阅paste.awesom.eu/4dym)。这不是未定义的行为。
  • 你能解释一下它是如何工作的,而不是仅仅说“不要用那个,用这个,它有效”?
  • 如果缓冲区有一些输入,这将起作用。如果它为空 getchar() 将强制控制台要求额外的输入,这意味着您需要单击额外的“输入”键来创建换行符。也许 fflush(stdin) 是一种不好的做法,但它可以防止这个问题
【解决方案2】:

始终在 Linux 上运行的一个:

#include <termios.h>
#include <unistd.h>

void clean_stdin()
{
        int stdin_copy = dup(STDIN_FILENO);
        /* remove garbage from stdin */
        tcdrain(stdin_copy);
        tcflush(stdin_copy, TCIFLUSH);
        close(stdin_copy);
}

您可以使用 tcraintcflush 不仅用于 in/out/err fd。

【讨论】:

    【解决方案3】:

    fflush 的行为没有为输入流定义 (online 2011 standard):

    7.21.5.2 fflush 函数

    概要

    1
    
        #include <stdio.h>
        int fflush(FILE *stream);
    
    说明

    2 如果流指向输出流或更新流,其中最近的 未输入操作,fflush 函数会导致该流的任何未写入数据 被交付到宿主环境中写入文件;否则,行为是 未定义。

    3 如果stream 是空指针,fflush 函数对所有 上面定义了行为的流。

    返回

    4 fflush 函数为流设置错误指示符,如果写入则返回 EOF 发生错误,否则返回零。

    【讨论】:

    • fflush 输入流上未在 POSIX.1-2001 中定义,但 在 POSIX.1-2008 中定义
    【解决方案4】:

    我在 LINUX 上工作时遇到了同样的问题,这个问题的替代解决方案可以是你定义一个虚拟字符让我们说char dummy; 并在您的实际输入发生之前放置一个scanf() 来扫描它。这对我有用。我希望它也对你有用。

    【讨论】:

      【解决方案5】:

      fflush() 对输入流没有多大作用,但由于scanf() 永远不会返回,这没关系。 scanf() 阻塞,因为在您按下 Enter

      之前,终端窗口不会向 C 程序发送任何内容

      你有两个选择:

      1. 输入10 回车
      2. 将终端置于原始模式。

      第二个选项有很多drawbacls,你会失去编辑能力,所以我建议逐行阅读输入。

      【讨论】:

        【解决方案6】:

        您必须包含并使用 __fpurge(无论您想要什么)。

        来自阿根廷的致敬

        【讨论】:

        • 你应该解释为什么你需要包含它,而不是仅仅说你这样做。
        【解决方案7】:

        在 scanf 之后使用 getchar() 代替

        【讨论】:

          【解决方案8】:
          #include<stdio.h>
          int main()
          {
          char ans='y';
          int a;
          while(ans=='y'||ans=='Y')
              {
          
               printf("Type a number:-");
               scanf("%d",&a);
               printf("square of number = %d\nwant to enter 
               number again(y/n)?\nANS=",a*a); 
               scanf("%s",&ans);//use %s in place of %c
               }
          return 0;
          }
          

          【讨论】:

          • 请在您的回答中添加一些描述
          【解决方案9】:

          通过在 Linux 中使用bzero(); 系统调用,我们可以刷新之前存储的值。
          请在终端输入man bzero 阅读bzero(); 的手册页。 试试这个例子

          #include<stdio.h>
          #include<string.h>
          
          int main()
          {
            char buf[]={'y'};
            int num;
            while(buf[0]=='y')
            {
              printf("enter number");
              scanf("%d",&num);
              printf("square of %d is %d\n",num,num*num);
              bzero(buf, 1);
              printf("want to enter y/n");
              scanf("%s",&buf[0]);
            }
            return 0;
          } 
          

          【讨论】:

          • 此代码将导致scanf("%s" 行上的缓冲区溢出。此外,buf[0] = 0;bzero(buf, 1) 更不容易出错。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-02-25
          • 2023-04-04
          • 2017-06-04
          • 2012-12-27
          • 1970-01-01
          • 2018-06-15
          • 2015-06-26
          相关资源
          最近更新 更多