【问题标题】:Can fseek(stdin,1,SEEK_SET) or rewind(stdin) be used to flush the input buffer instead of non-portable fflush(stdin)?是否可以使用 fseek(stdin,1,SEEK_SET) 或 rewind(stdin) 来刷新输入缓冲区,而不是使用不可移植的 fflush(stdin)?
【发布时间】:2013-05-21 14:35:11
【问题描述】:

由于我发现fflush(stdin) 不是处理熟悉的“输入缓冲区中的换行符”问题的可移植方法,所以当我必须使用以下方法时,我一直在使用以下方法 使用scanf:

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

但今天我偶然发现了我从cplusplus.com on fflush 注意到的这条线:

fflush()...在为更新而打开的文件中(即,为读取和写入而打开),流应在输出操作之后刷新,然后再执行输入操作。这可以通过重新定位(fseek、fsetpos、rewind)或显式调用 fflush 来完成

事实上,我之前已经读过很多次了。所以我想确认我是否可以在scanf() 之前简单地使用以下任何一个来实现fflush(stdin) 在支持时所服务的相同目的:

fseek(stdin,1,SEEK_SET);
rewind(stdin);

PS rewind(stdin) 似乎很安全并且可以刷新缓冲区,我错了吗?

错误如果我们谈论的是stdin,我应该提到fseek(stdin,0,SEEK_SET),因为在这种情况下我们不能使用除0或ftell()返回的任何偏移量。

【问题讨论】:

  • 根据您的报价,“... 输出操作后应刷新流 ...”。您是否希望在stdin 上执行输出操作,以要求fflush(stdin)?这似乎很愚蠢!你想write到一个read-only流吗?!为什么不描述 刷新缓冲区 的含义,或者您希望 fflush(stdin) 做什么?您可能还想考虑fflush 根据a non-C++ manual 实际做了什么。毕竟这是 C,不是 C++……
  • @undefinedbehaviour 这不是我的引述。这来自cplusplus.com/reference/cstdio/fflush,它涉及两个 I/O 流,而不是特别是 stdin。我的意思是,当从 stdin 阅读时,根据那段,我们可以使用rewind()fseek() 来刷新它。
  • stdin 仅供阅读,不可更新(读写)。不要混淆这两种模式。该网站严重不准确的情况并不少见。查找另一个手动站点。我推荐 opengroup。
  • @undefinedbehaviour 好吧,我从来没有说过我打算写到stdin。我的意思是,如果之前的 Enter 键还有一个换行符,那为什么可以我们不是在上面使用fseek()rewind()(为了刷新它)。你的意思是说stdin 不可搜索?是这样吗?
  • 没有。我的意思是说 stdin 不可写fflush 导致数据被写入。点击我第一条评论中的链接,你会看到的。有三种访问模式:打开读取、打开写入和打开更新。 刷新它是什么意思?在不使用 flush 一词的情况下定义这个过程(因为那是胡言乱语),你会发现即使文件是可搜索的,seek 也无济于事。

标签: c fseek fflush input-buffer


【解决方案1】:

这是唯一可以使用的可移植习语:

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

包括this 在内的几个线程解释了为什么feesk 通常不起作用。出于同样的原因,我怀疑rewind 也可以工作,实际上手册页说它相当于:

(void) fseek(stream, 0L, SEEK_SET)

【讨论】:

  • 我阅读了您提供的链接。但似乎有点难以理解。您能否将链接中与此问题相关的部分简单地写成几行?
  • @Jugni 这个评论真的很好解释stackoverflow.com/questions/4917801/… 基本上流没有存储在任何地方。如果您想四处寻找数据,请将其读入内存。
  • 但是我读到的流是默认缓冲的。我很确定stdinstdout是缓冲的。就像所有用fopen()打开的流一样
  • 我的意思是,通常当我们使用fopen()打开一个文件时,它首先被读入缓冲区/内存,因为这样更快,而不是每次都从磁盘读取。
  • @Jugni 否。C11 标准关于fopen “当打开时,当且仅当可以确定它不引用交互式设备时,流才会被完全缓冲。 " ...关于fseek "对于文本流,偏移量应为零,或偏移量应为先前成功调用相关流上的 ftell 函数返回的值具有相同的文件,并且应该是 SEEK_SET。” ...因此,即使您确实有可搜索的stdin(例如,它是从文件中通过管道传输的),它也可能是文本流(例如在 Windows 上) ),你不应该在你的问题中寻求...
猜你喜欢
  • 1970-01-01
  • 2014-01-15
  • 2011-11-28
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 2015-08-20
  • 1970-01-01
  • 2014-05-01
相关资源
最近更新 更多