1

我从一开始就在想为什么不能刷新输入缓冲区fseek(stdin,0,SEEK_SET)rewind(stdin)因为它清楚地写在cplusplusreference调用这两个函数刷新缓冲区(输入或输出无关)。但由于整个想法似乎是新的,我把它放进去昨天一个笨拙的问题。

是否可以使用 fseek(stdin,1,SEEK_SET) 或 rewind(stdin) 来刷新输入缓冲区,而不是使用不可移植的 fflush(stdin)?

而且我对我得到的答案持怀疑态度,这似乎表明我做不到。坦率地说,我看不出为什么不这样做。今天我自己尝试了它并且它有效newline lurking in stdin我的意思是,为了在使用多个语句时处理问题scanf(),似乎我可以使用fseek(stdin,0,SEEK_SET)rewind(stdin)代替 non-portable 和UB fflush(stdin)

请告诉我这是否是没有任何风险的正确方法。到目前为止,我一直在使用以下代码来处理newline in stdinwhile((c = getchar()) != '\n' && c != EOF);。下面是我的代码:

#include <stdio.h>

int main ()
{
    int a,b;
    char c;
    printf("Enter 2 integers\n");
    scanf("%d%d",&a,&b);
    printf("Enter a character\n");

    //rewind(stdin);   //Works if activated
    fseek(stdin,0,SEEK_SET);  //Works fine

    scanf("%c",&c);  //This scanf() is skipped without fseek() or rewind()
    printf("%d,%d,%c",a,b,c);

}

在我的程序中,如果我不使用fseek(stdin,0,SEEK_SET)or rewind(stdin),则跳过第二个scanf()始终fseek(stdin,0,SEEK_SET)使用换行符。如果我使用or ,问题就解决了rewind(stdin)

4

2 回答 2

1

我不确定你在哪里读到cplusplusreference(不管是什么),刷新到行尾是强制行为。

我能找到的最接近的匹配项,http://www.cplusplus.com/reference/cstdio/fseek/http://www.cplusplus.com/reference/cstdio/rewind,根本不提冲洗,除了参考fflush().

无论如何,C 标准中也没有规定这种行为。C11 7.20.9.2 fseekand 7.20.9.5 rewind(毕竟,fseek与零偏移量和相同SEEK_SET)也没有提到冲洗。

他们所说的只是文件指针被移动到流中的相关位置。

因此,就这在您的环境中有效的程度而言,我们只能说这在您的环境中有效。它可能无法在其他地方工作,甚至可能在未来某个不确定的时间点停止在您的环境中工作。


如果您真的想要强大的输入,您应该使用两阶段方法,fgets检索一行,然后sscanf从该行中获取您想要的内容。混合两种输入范式 (scanfgetchar) 经常会出现问题。

可以在此处找到一个好的(强大的、错误检查和清除到行尾的)输入功能。

于 2013-05-22T06:17:03.050 回答
-2

我之前测试过,我检查了 fseek 在标准输入上不起作用。fseek() 通常在磁盘上的文件上工作,因此出于某些安全原因,内核似乎禁止访问 stdin。无论如何,很高兴看到谁和我一样想。Tnx 的好问题。

于 2013-12-14T08:26:15.733 回答