getchar、putchar和getc、puts的问题。
#include <stdio.h>
int main()
{
char c;
while((c = getchar()) != EOF)
putchar(c);
return 0;
}
运行结果
int main()
{
char foor[20];
while(gets(foor) != NULL)
puts(foor);
return 0;
}
运行结果
以上两个程序,均是死循环。运行效果完全相同。?
[解决办法]
均是死循环?
不是的,getchar和gets都有返回NULL的时候,这时while的条件就不满足了,循环就结束了;
那它们什么时候返回NULL呢?当它们读到EOF的时候;
那控制台怎么输入EOF呢?Windows下就是Ctrl+Z
运行效果完全相同?
也不是的,看上去一样,实际运行的原理还是不一样的。
getchar每次读入一个字符,gets每次读一行(但会丢弃回车),这就是它们的区别;
为什么都是回车之后才有反应?因为标准IO都是有缓冲的,而且是行缓冲,
这意味着“标准输入流”只有在按回车之后,输入的东西才会进入流(输入的东西也包括了回车)
比如,刚进入程序,“标准输入流”中没有任何东西,这时getX会等待输入(还没有进循环体)
用户输入abc,“标准输入流”还是没有东西,直到用户输入回车<cr>,这时“标注输入流”中才有东西:
abc<cr>
这时标准输入流有东西了,getX可以返回了,
getchar从stdin中读入一个字符a,返回该字符,该字符不为NULL,进入循环体,putchar该字符;然后又回到while,读入下一个字符b,不为NULL,putchar该字符,一直到<cr>,getchar读入<cr>,不为NULL,putchar <cr>产生回车效果,这时stdin空了,等待用户的下一次输入
而gets从stdin中读入abc<cr>,并将abc存入foor(<cr>丢弃),由于成功读入,gets返回foor,它并不是NULL,从而导致进入循环体,puts将输出foor,即abc,同时puts会多输出个回车,然后又回到while,这时stdin已空,程序停下来等待用户的下一次输入
由此可以发现,用户输入
abc<cr>
getchar while了四次,而gets只while了一次,这就是它们区别的表现,单纯看输入输出是看不出来的,可以通过debugger跟踪程序的运行,来理解while的过程;也可以通过加一个循环counter,来跟踪while的次数。
核心概念:流
[解决办法]
while((c = getchar())!=EOF)
{
putchar(c);
}