说起getchar()函数,最典型的例子就是《The C Programming Language》上的例子:
#include <stdio.h>
/* copy input to output; 2nd version */
main()
{
int c;
while ((c = getchar()) != EOF)
putchar(c);
}
=====================================================================================================
C99对EOF的描述如下:
which expands to an integer constant expression, with type int and a negative value, that
is returned by several functions to indicate end-of-file, that is, no more input from a
stream;
获知EOF是int型的负数常量(一般都把EOF宏定义为-1)
=====================================================================================================
*********************************************************************************************************************************************
首先来说说为什么getcha()函数的返回值是int型的?
网络上的解释如下:
char型不能容纳所有的字符,特别是,可能无法容纳EOF,所以会导致如下问题:
① 某些合法的输入字符在被“截断”后的值可能与EOF相等,这就会导致程序提前终止
② char型根本不可能取到EOF的值,导致程序死循环
③ 有些编译器确实对函数返回值做了截取,将低端字节复制给char型,但在比较c与EOF时却比较的是函数的返回值与EOF,这就导致声明c为char型时程序的执行是正确的。
我的疑问如下:
① getchar()函数返回的值到底是不是都是ASCII呢(ASCII的范围为0~127)?如果是,那就算发生截取,也不会影响结果,因为高位都是0。如果不是(例如汉字),那么发生截取后的值是有可能与EOF相等的,例如返回一个值为0x000001ff, 截取后的值为EOF,这就明显发生错误了。
问题是getchar函数到底能不能处理汉字,我试了下,是可以的。
② 标准只说EOF是int型的负常量,那么会不会有其他负值,而不是-1呢?
如果getchar函数只能处理ASCII码范围内的数字,那么我们显示声明c为signed char(-128 ~127)的行不行呢?应该是不行的,应该EOF有可能取值不在这个范围内(例如-129)。
综上所述,推荐使用int c,因为这样是肯定不会出错的。
http://blog.sina.com.cn/s/blog_6057ff5301014e0t.html
*********************************************************************************************************************************************
第二个想讨论的是关于这个程序的输入输出问题。
首先要明白的是getchar函数是以行为单位存取的,什么意思呢?
运行程序,我们发现并不是我们输入一个字符就显示一个字符,而是等我们按了回车之后才一起显示我们刚刚输入的字符,并换行等待我们的再次输入。
输入的字符并不会立刻显示在屏幕上,而是先存储在键盘缓冲区中,待我们按了回车键后才从缓冲区发送给我们的程序。
不知道大家想过没有,我们明明按的是回车怎么就换行了呢? 回车与换行的ASCII并不相同啊
所以当我们按了回车键时相当于做了两件事,①在缓冲区末添加换行符\n(而不是回车\r),②接着发送缓冲区的内容给我们的程序。我们的程序接收到发送来的程序后在屏幕上打印字符,并在另一行的开始等待输入。
注意,为什么是另一行的开始呢? 换行符只管换行,并不管在一行的哪里啊
原来程序在接收到数据后,改变了我们的数据,原来的数据是xxx\n, 改变后成了xxx\r\n.
整个过程总结如下:
① 程序在用户按了回车键后才接收数据
② 程序将用户输入的回车(ASCII码为13)看做换行符(ASCII码为10)
③ 程序发送的是换行符,但终端接收的是回车换行符
关于程序接收EOF要分两种情况来定:(个人猜测)
第一种情况是缓冲区有字符, 这种情况下,程序不在缓冲区中添加任何内容,原样打印出缓冲区内容,并等待我们输入
第二种情况是缓冲区没有字符,这种情况下,程序在缓冲区中原样添加EOF所代表的数值,所以程序条件成立退出。
当我们通过stty raw命令改变终端的属性后,我们发现现在是输入一个字符就立刻显示一个字符,并且EOF都不起效果了,甚至Ctrl+C都中断不了,这其中为什么,估计是要了解系统是如何实现这些机制的了。