1.getchar()是标准I/O标准库里的库函数 原型是int getchar(void)-----------它没有参数,原因是因为它是从stdin标准输入流中读入一个字符的函数,已经有了默认的流参数stdin了。其返回值是一个整型数,是用来表示字符用的。 输入输出往往都是内存与外设之间的数据来往,但是,内存的运行效率比外设的运行效率那要大得多,比如,从内存写一个字符到磁盘上,内存很快地传出字符数据,供给磁盘存储,磁盘花了很多的时间来存储,在这段存储的时间里,我们宝贵的内存只能干等着磁盘做完存储操作来传递下一个字符,这样的做法是非常浪费内存的。所以计算机牛人们就设计出了缓冲的概念,来缓和内存与外设之间速度不匹配的问题。这意味着程序的输入输出已经不是跟外设直接打交道了,而是从一块被称为缓冲区的内存区域来回复制数据。就C程序而言,所有的IO操作只是简单地从程序移进移出字节,这种字节流即为流。 回到getchar()函数中来,我们以下面一个程序为例。 #include<stdio.h> 第一种情况:如果你的输入只有一个字符,那么肯定的,ch1的值便是这个字符,那么ch2呢?在这里别忘了,你输完前一个字符后是通过什么结束输入的?是的,是Enter,Enter肯定会说:“人家可也是个正正经经的字符啊,不要不把无字幕的字符不当字符啊!”是的,在这里是向缓冲区中输入了两个字符,而getchar()是做什么呢?前面提到了,程序可不是直接跟外设打交道的,而是跟缓冲区打交道的,所以,getchar()库函数是从缓冲区中读取字符而不是从键盘读取字符的,所以,你已经向缓冲区中输入了两个字符够上面程序中两个getchar()读的了。可以用下面的程序测试一下这种效果。
如果在第一次输入的时候不是简单的输入一个字符和一个换行,而是输入了一大堆字符,那么,这些字符将全部送往stdin流的缓冲区中,后面的所有包括getchar()的将从stdin流中读入数据的库函数将从这个缓冲区中读入数据,直道缓冲区再次为空后,才提示输入设备准备输入数据。 一、getchar的两点总结: while((c = getchar()) != EOF){ 执行程序,输入:abc,然后回车。则程序就会去执行puchar(c),然后输出abc,这个地方不要忘了,系统输出的还有一个回车。然后可以继续输入,再次遇到换行符的时候,程序又会把那一行的输入的字符输出在终端上。
对这个问题的一个解释是,在大师编写C的时候,当时并没有所谓终端输入的概念,所有的输入实际上都是按照文件进行读取的,文件中一般都是以行为单位的。因 此,只有遇到换行符,那么程序会认为输入结束,然后采取执行程序的其他部分。同时,输入是按照文件的方式存取的,那么要结束一个文件的输入就需用到EOF (Enf Of File). 这也就是为什么getchar结束输入退出时要用EOF的原因。 2.getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。 这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们会写这样的两行代码: 这样就很有可能出现问题。因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)即文件结束符EOF时,getchar ()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不 正确的。为了能够让所定义的变量能够包含getchar函数返回的所有可能的值,正确的定义方法如下(K&R C中特别提到了这个问题): 二、EOF的两点总结(主要指普通终端中的EOF) EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。 2.EOF作为行结束符时的情况,这时候输入Ctrl+D并不能结束getchar(),而只能引发getchar()提示下一轮的输入。 这种情况主要是在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+D,此时的Ctrl+D并不是文件 结束符,而只是相当于换行符的功能,即结束当前的输入。以上面的代码段为例,如果执行时输入abc,然后Ctrl+D,程序输出结果为: 注意:第一组abc为从终端输入的,然后输入Ctrl+D,就输出第二组abc,同时光标停在第二组字符的c后面,然后可以进行新一次的输入。这时如果再次输入Ctrl+D,则起到了文件结束符的作用,结束getchar()。 从这里也可以看出Ctrl+D和换行符分别作为行结束符时,输出的不同结果。 EOF的作用也可以总结为:当终端有字符输入时,Ctrl+D产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;当终端没有字符 输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+D,此时产生的EOF相当于文件结束符,程序将结束getchar()的执行。 顺便提一下输出库函数。输出库函数的效果也只是将程序中的内容输出到缓冲区中,然后再刷新的时候输出到外设上,如果在输出的时候输出输出流stdout缓冲区中已经有了数据,那么输出的是已经有的内容,而不一定是你输出的内容。这是由缓冲区刷新的时间控制的,刷新的操作是根据具体的编译器来决定的,一般调用fflush(stdout)来刷新一下stdout缓冲区。 |
|