这是刷新C输入流的正确方法吗?

好吧,我一直在google上搜索很多关于如何正确刷新输入流的问题。 我所听到的只是关于输入流如何定义fflush()的混合论据,有些人说这样做,而其他人只是说不要这样做,我没有太多运气找到明确的效率/这样做的正确方法,大多数人都同意..我在编程方面很陌生,所以我还不知道该语言的所有语法/技巧,所以我的问题是哪种方式是最有效/最合适的解决方案清除C输入流??

  1. 在尝试接收更多输入之前,请使用getchar()两次?

  2. 只需在输入上使用fflush()函数? 要么

  3. 这就是我认为我应该这样做的方式。

     void clearInputBuf(void); void clearInputBuf(void) { int garbageCollector; while ((garbageCollector = getchar()) != '\n' && garbageCollector != EOF) {} } 

所以,每当我需要读取一个新的scanf(),或者使用getchar()来暂停程序时,我只需要调用clearInputBuf ..那么这三种解决方案中最好的方法是什么呢?还是有更好的选择?

我所听到的只是关于如何为输入流定义fflush()的混合论点

那是对的。 不要使用fflush()来刷新输入流。

(A)适用于在输入流中保留单个字符的简单情况(例如scanf()留下换行符)。

(B)不要使用。 它是在某些平台上定义的。 但是不要依赖什么标准调用未定义的行为

(C)显然是3个选项中最好的,因为它可以“刷新”输入流中的任意数量的字符。

但是如果你读取 (例如使用fgets() ),你可能更不需要清除输入流。

这取决于你所认为的“刷新输入流”。

对于输出流,刷新操作确保已写入流但已在内存中保持缓冲的所有数据都已刷新到基础文件系统文件。 这是一个非常明确的操作。

对于输入流,没有明确定义的操作来清理流应该做什么。 我会说这没有任何意义。

C标准库的一些实现重新定义了输入流的“刷新”的含义,意味着“清除当前行的其余部分尚未读取”。 但这完全是武断的,其他实现选择什么都不做。

从C11开始,这种差异已得到纠正,标准现在明确指出fflush()函数不能与输入流一起使用,正是因为它没有意义,我们不希望每个运行时库供应商都在其他任何地方实现它他们的感觉。

因此,请务必按照您的方式继续实现您的clearInputBuf()函数,但不要将其视为“刷新输入流”。 哪有这回事。

事实certificate,这取决于平台。

fflush()不能将输入流作为参数,因为根据c标准,因为行为没有在任何地方定义,所以它的行为不明确。

  • 在Windows上, fflush()有一个已定义的行为,它fflush()您的需要。

  • 在Linux上,有fpurge(3)可以做你想做的事情。

最好的方法是简单地读取循环中的所有字符,直到

  1. 找到换行符。
  2. EOFgetchar()返回。

喜欢你的clearInputBuf()函数。

请注意,刷新输出流意味着将所有未写入的数据写入流中,仍在缓冲区中的数据等待刷新。 但是从流中读取所有未读的字节并不具有相同的含义。

这就是fflush()输入流没有意义的原因。 另一方面, fpurge()是专门为此设计的,它的名字是更好的选择,因为你想要清除输入流并重新开始。 问题是,它不是标准function。

阅读fpurge(3)应该澄清为什么fflush(stdin)是未定义的行为,以及为什么类似于Windows上的实现没有意义,因为它使得fflush()在不同的输入上表现不同。 这就像让c符合PHP一样。

问题比它看起来更加微妙:

  • 在具有复杂终端设备的系统上,例如unix和OS / X,来自终端的输入被缓冲在两个不同的级别:系统终端使用缓冲区来处理行编辑,从仅使用退格校正输入到使用光标的全行编辑和控制键。 这称为熟食模式。 在系统中缓冲整行输入,直到输入回车键或输入文件结束键组合。

  • FILE函数执行自己的缓冲,默认情况下,对与终端关联的流进行行缓冲。 默认情况下设置为BUFSIZ的缓冲区大小和在消耗缓冲内容时从系统请求字节。 对于大多数请求,将从系统读取整行到流缓冲区,但在某些情况下,例如当缓冲区已满时,只有部分行将在scanf()返回时从系统中读取。 这就是为什么丢弃流缓冲区的内容可能并不总是足够的。

刷新输入缓冲区可能意味着不同的事情:

  • 丢弃用户为响应输入请求(如getchar()fgets()scanf()而输入的额外输入,包括换行符。 在scanf()的情况下,需要刷新此输入尤为明显,因为大多数格式行不会导致换行消耗。

  • 丢弃任何待处理的输入并等待用户按键。

您可以为第一种情况实现可移植的fluchfunction:

 int flush_stream(FILE *fp) { int c; while ((c = getc(fp)) != EOF && c != '\n') continue; return c; } 

这正是您的clearInputBuf()函数为stdin所做的。

对于第二种情况,没有可移植的解决方案,并且系统特定的方法是非常重要的。