fseek(stdin,0,SEEK_SET)和倒带(stdin)真的刷新输入缓冲区“stdin”。可以使用它们吗?

时间:2013-05-22 05:57:42

标签: c stdin fseek fflush

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

Can fseek(stdin,1,SEEK_SET) or rewind(stdin) be used to flush the input buffer instead of non-portable fflush(stdin)?

我对我得到的答案表示怀疑,这似乎暗示我无法做到。坦率地说,我没有理由不这样做。今天我自己尝试了,它有效 !!我的意思是,要在使用多个newline lurking in stdin声明的同时处理scanf()问题,似乎我可以使用fseek(stdin,0,SEEK_SET)rewind(stdin)代替非便携式和<{1}} strong> 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)rewind(stdin),则跳过第二个scanf(),并将换行符始终作为如果我使用fseek(stdin,0,SEEK_SET)rewind(stdin)

,问题就解决了

2 个答案:

答案 0 :(得分:1)

我不确定你在cplusplusreference上读到的(无论是什么),刷新到行尾就是强制行为。

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

无论如何,C标准中没有任何内容要求这种行为。 C11 7.20.9.2 fseek7.20.9.5 rewind(毕竟,与fseek相同,零偏移和SEEK_SET)也没有提及冲洗。

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

因此,就您的环境而言,我们可以说的是,这适用于您的环境。它可能在其他地方不起作用,它甚至可能停止在未来的不确定点在你的环境中工作。


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

可以找到一个好的(健壮的,错误检查,并在需要时清除到行尾)输入函数here

答案 1 :(得分:-1)

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