我从一开始就在思考为什么不能fseek(stdin,0,SEEK_SET)
和rewind(stdin)
刷新输入缓冲区,因为它在cplusplusreference
中清楚地写入了调用这两个函数来刷新缓冲区(输入或输出无论如何)。但由于整个想法似乎是新的,我昨天把它放在了一个笨拙的问题。
我对我得到的答案表示怀疑,这似乎暗示我无法做到。坦率地说,我没有理由不这样做。今天我自己尝试了,它有效 !!我的意思是,要在使用多个newline lurking in stdin
声明的同时处理scanf()
问题,似乎我可以使用fseek(stdin,0,SEEK_SET)
或rewind(stdin)
代替非便携式和<{1}} strong> UB fflush(stdin)
。
请告诉我这是否是一种没有任何风险的正确方法。到目前为止,我一直在使用以下代码来处理newline in stdin
:while((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)
。
答案 0 :(得分:1)
我不确定你在cplusplusreference
上读到的(无论是什么),刷新到行尾就是强制行为。
我能找到的最接近的匹配http://www.cplusplus.com/reference/cstdio/fseek/和http://www.cplusplus.com/reference/cstdio/rewind,除了参考fflush()
之外,根本没有提及冲洗。
无论如何,C标准中没有任何内容要求这种行为。 C11 7.20.9.2 fseek
和7.20.9.5 rewind
(毕竟,与fseek
相同,零偏移和SEEK_SET
)也没有提及冲洗。
他们所说的全部是文件指针被移动到流中的相关位置。
因此,就您的环境而言,我们可以说的是,这适用于您的环境。它可能在其他地方不起作用,它甚至可能停止在未来的不确定点在你的环境中工作。
如果您真的需要强大的输入,那么您应该使用两阶段方法fgets
来检索一行,然后sscanf
来获取您想要的那一行。混合两种输入范例(scanf
和getchar
)经常会出现问题。
可以找到一个好的(健壮的,错误检查,并在需要时清除到行尾)输入函数here。
答案 1 :(得分:-1)
我刚刚测试过,我检查过fseek对stdin不起作用。 fseek()通常在磁盘上的文件上工作,因此出于某些安全原因,似乎禁止内核访问stdin。无论如何,很高兴看到谁像我一样。 Tnx是个好问题。