今日用ubuntu终端调试K&R 1.5节的getchar程序时,遇到了困惑,成果发现了一篇好文章,转载于此。
getchar()和EOF总结
大师级经典的作品,要咬文嚼字的去读,去了解。曾经在看K&R的The C Programming Language(SecondEdition)
第1.5节的字符输入/输出,被getchar()和EOF所利诱了。或许首要仍是因为没有搞清楚getchar()的作业原理和EOF的用法。因而,感觉很有必要总结一下,否则,许多琐碎的知识点长期往后就会淡忘的,只要写下来才是最好的办法。
其实,getchar()最典型的程序也就几行代码罢了。自己所用的环境是DebianGNU/Linux,在其他体系下也相同。
一、getchar的两点总结:
1.getchar是以行为单位进行存取的。
当用getchar进行输入时,假如输入的榜首个字符为有用字符(即输入是文件完毕符EOF,Windows下为组合键Ctrl+Z,Unix/Linux 下为组合键Ctrl+D),那么只要当最终一个输入字符为换行符(也可所以文件完毕符EOF,EOF将在后边评论)时,getchar才会中止履行,整个程序将会往下履行。
while((c = getchar()) != EOF){
putchar(c);
}
履行程序,输入:abc,然后回车。则程序就会去履行puchar(c),然后输出abc,这个当地不要忘了,体系输出的还有一个回车。然后能够持续输入,再次遇到换行符的时分,程序又会把那一行的输入的字符输出在终端上。
关于getchar,必定许多初学的朋友会问,getchar不是以字符为单位读取的吗?那么,已然我输入了榜首个字符a,必定满意while循环(c = getchar()) != EOF的条件阿,那么应该履行putchar(c)在终端输出一个字符a。不错,我在用getchar的时分也是一向这么想的,可是程序就偏偏不着样履行,而是必需读到一个换行符或许文件完毕符EOF才进行一次输出。
对这个问题的一个解说是,在大师编写C的时分,其时并没有所谓终端输入的概念,一切的输入实际上都是依照文件进行读取的,文件中一般都是以行为单位的。因而,只要遇到换行符,那么程序会以为输入完毕,然后采纳履行程序的其他部分。一起,输入是依照文件的办法存取的,那么要完毕一个文件的输入就需用到EOF(Enf Of File). 这也便是为什么getchar完毕输入退出时要用EOF的原因。
2.getchar()的回来值一般状况下是字符,但也或许是负值,即回来EOF。
这儿要着重的一点便是,getchar函数一般回来终端所输入的字符,这些字符体系中对应的ASCII值都对错负的。因而,许多时分,咱们会写这样的两行代码:
char c;
c = getchar();
这样就很有或许出现问题。因为getchar函数除了回来终端输入的字符外,在遇到Ctrl+D(Linux下)即文件完毕符EOF时,getchar() 的回来EOF,这个EOF在函数库里一般界说为-1。因而,在这种状况下,getchar函数回来一个负值,把一个负值赋给一个char型的变量是不正确的。为了能够让所界说的变量能够包括getchar函数回来的一切或许的值,正确的界说办法如下(K&R C中特别提到了这个问题):
int c;
c = getchar();
二、EOF的两点总结(首要指一般终端中的EOF)
1.EOF作为文件完毕符时的状况:
EOF尽管是文件完毕符,但并不是在任何状况下输入Ctrl+D(Windows下Ctrl+Z)都能够完成文件完毕的功用,只要在下列的条件下,才作为文件完毕符。
(1)遇到getcahr函数履行时,要输入榜首个字符时就直接输入Ctrl+D,就能够跳出getchar(),去履行程序的其他部分;
(2)在前面输入的字符为换行符时,接着输入Ctrl+D;
(3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+D,这时第2次输入的Ctrl+D起到文件完毕符的功用,至于榜首次的Ctrl+D的效果将在下面介绍。
其实,这三种状况都能够总结为只要在getchar()提示新的一次输入时,直接输入Ctrl+D才相当于文件完毕符。
2.EOF作为行完毕符时的状况,这时分输入Ctrl+D并不能完毕getchar(),而只能引发getchar()提示下一轮的输入。
这种状况首要是在进行getchar()新的一行输入时,当输入了若干字符(不能包括换行符)之后,直接输入Ctrl+D,此刻的Ctrl+D并不是文件完毕符,而仅仅相当于换行符的功用,即完毕当时的输入。以上面的代码段为例,假如履行时输入abc,然后Ctrl+D,程序输出成果为:
abcabc
留意:榜首组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,一起光标停在第二组字符的c后边,然后能够进行新一次的输入。这时假如再次输入Ctrl+D,则起到了文件完毕符的效果,完毕getchar()。
假如输入abc之后,然后回车,输入换行符的话,则终端显现为:
abc //榜首行,带回车
abc //第二行
//第三行
其间榜首行为终端输入,第二行为终端输出,光标停在了第三行处,等候新一次的终端输入。
从这儿也能够看出Ctrl+D和换行符别离作为行完毕符时,输出的不同成果。
EOF 的效果也能够总结为:当终端有字符输入时,Ctrl+D发生的EOF相当于完毕本行的输入,将引起getchar()新一轮的输入;当终端没有字符输入或许能够说当getchar()读取新的一次输入时,输入Ctrl+D,此刻发生的EOF相当于文件完毕符,程序将完毕getchar()的履行。
【弥补】本文第二部分中关于EOF的总结部分,适用于终端驱动处于一次一行的形式下。也便是尽管getchar()和putchar()确实是依照每次一个字符 进行的。可是终端驱动处于一次一行的形式,它的输入只要到“”或许EOF时才完毕,因而,终端上得到的输出也都是按行的。
假如要完成终端在读一个字符就完毕输入的话,下面的程序是一种完成的办法(参阅《C专家编程》,略有改动)
#include
#include
int
main(void)
{
int c;
system(“stty raw”);
c = getchar();
putchar();
system(“stty cooked”);
return 0;
}
编译运转该程序,则当如入一个字符时,直接出处一个字符,然后程序完毕。
由此可见,因为终端驱动的形式不同,造成了getchar()输入完毕的条件不相同。一般形式下需求回车或许EOF,而在一次一个字符的形式下,则输入一个字符之后就完毕了。
期望本文能够对初学C的朋友供给一点协助,也期望能和其他朋友进行沟通。其间了解不对的当地若能得到纠正和主张,自己将不胜感激。一起,本文参阅了chinaunix.net关于getchar评论的帖子和一位博友的文章,链接地址别离为:
http://blog.chinaunix.net/u/9861/showart_64652.html
http://bbs.chinaunix.net/viewthread.php … ra=&page=1
欢迎沟通和纠正