C 关于fgets()和stdin一起使用的机制
我想更好地了解如何使用C 关于fgets()和stdin一起使用的机制,c,stdin,fgets,C,Stdin,Fgets,我想更好地了解如何使用fgets()和stdin。 以下是我的代码: int main() { char inputBuff[6]; while(fgets(inputBuff, 6, stdin)) { printf("%s", inputBuff); } return 0; } 假设我的输入是aaaabbbb,然后按Enter键。通过使用loopcount,我了解到在下一次输入之前,实际上循环将运行两次(包括我输入的那一次) 循环1:
fgets()
和stdin
。
以下是我的代码:
int main()
{
char inputBuff[6];
while(fgets(inputBuff, 6, stdin))
{
printf("%s", inputBuff);
}
return 0;
}
假设我的输入是aaaabbbb
,然后按Enter键。通过使用loopcount,我了解到在下一次输入之前,实际上循环将运行两次(包括我输入的那一次)
循环1:键入字符后,aaaabbbbb\n
将存储在stdin
文件流的缓冲区中。而fgets()
将从文件流中检索特定数量的数据,并将它们放入inputBuff
。在这种情况下,它将一次检索5(6-1)个字符。这样,当fgets()
已经运行一次时,inputBuff
将存储aaaab
,然后进行打印
循环2:然后,由于bbb\n
留在文件流中,fgets()
将第二次执行,以便inputBuff
包含bbb\n
,然后被打印
循环3:当文件流到达末尾(EOF
)时,程序将请求我的输入(第二次)
问题:似乎
fgets()
只会在stdin
流的缓冲区中没有剩余数据(EOF
)之后才要求我输入键盘。我只是想知道为什么我不能使用键盘在循环2中输入任何内容,而fgets()
只需继续从stdin
流中检索5个字符,并将多余的数据保留在文件流中以备下次检索。我对stdin
或fgets()
有任何误解吗?谢谢你抽出时间 fgets()
只在'\n'
或EOF
之前读取。之后的所有内容都将保留在stdin
中,因此在再次调用fgets()
时将被读取。但是,您可以从stdin
中删除多余的字符,例如使用getc()
,直到到达'\0'
。您可能需要查看手册页以了解这一点。所有内容都在fgets()的手册页中。
无论您要求什么。只需要正确地阅读它,它说
char*fgets(char*s,int-size,FILE*stream)代码>
fgets()读取的字符数最多比sizecharacters少一个
并将它们存储到s指向的缓冲区中。阅读
在EOF或换行符后停止。如果读取了换行符,则为
存储到缓冲区中。存储一个终止的空字节(aq\0aq)
在缓冲区中最后一个字符之后
如果输入为aaaabbbb
且在fgets()中
您指定大小为6
的第二个参数,即它将少读一个5
字符,并将添加终止\0
,因此第一次inputBuff
保持aaaaaab
,并且由于仍然EOF
或\n
没有出现,因此下次inputBuff
保持bbb\n
新行也最终被存储
此外,还应检查fgets()
的返回类型,并检查\n
是否发生,然后断开循环。例如
char *ptr = NULL;
while( (ptr = fgets(inputBuff, 6, stdin))!= NULL){
if(*ptr == '\n')
break;
printf("%s", inputBuff);
}
程序的行为比您预期的更微妙:
fgets(inputBuff,6,stdin)
从stdin
读取最多5个字节,并在获取存储到目标数组中的换行符时停止读取
因此,当您正确诊断时,第一个调用读取5字节aaab
并打印它们,第二个调用读取4字节bbb\n
并打印它们,然后第三个调用获取一个空输入流并等待用户输入
棘手的部分是stdin
如何从用户那里获取输入,也称为控制台输入
默认情况下,控制台输入和stdin
通常都是行缓冲的,因此无论传递给fgets()
的缓冲区大小如何,都可以键入完整的输入行。但是,如果您可以将stdin
设置为未缓冲,将控制台输入设置为未煮熟,那么第一个fgets()
确实会在您键入前5个字节后立即读取它们
控制台输入是一个复杂的主题。下面是一篇关于其内部运作的深入文章:现实在什么程度上偏离了你的预期还不太清楚。您能显示产生意外输出的输入吗?在Fine手册中:
fgets()从流中最多读取一个小于大小的字符,并将它们存储到s指向的缓冲区中。EOF或换行符后,读取停止。如果新行被读取,它将被存储到缓冲区中。“\0”存储在缓冲区中最后一个字符之后。
是否希望丢弃“bbb\n”
,并请求新的输入?如果是这样的话,当一行的长度事先未知时,程序怎么能读取它呢?你说的“我只是想知道为什么我不能用键盘在循环2中输入任何东西,而fgets()只能继续从stdin流中检索5个字符…”到底是什么意思?您是否想在前一个字符串中间插入一些东西(在<代码> BBB\N/COD>之前),或者有<代码> FGES读取新行,或者什么?对不起,我有一些编码任务要做,所以我不能马上回复您的评论。很抱歉这么晚才回复@n、 没有,我没有收到任何意外的输出。只是想知道为什么“有时”每当调用fgets()时,我没有被要求输入某个内容。Thx提醒我需要添加一个条件以打破循环。“fgets()从流中最多读入一个小于sizecharacters的字符,并将它们存储到s指向的缓冲区中。读取在EOF或换行后停止。”这是否意味着fgets()在缓冲区中存储“aaaab”后还没有完成其“第一次”读取输入过程?