getchar()、putchar()和EOF

本文详细介绍了C语言中的字符输入/输出函数getchar()和EOF的概念。getchar()以行为单位读取字符,通常在读取到换行符或EOF时停止。EOF是文件结束的标志,其值为-1。在不同环境下,Ctrl+Z(Windows)或Ctrl+D(Unix/Linux)可以产生EOF,但具体何时作为文件结束符需要特定条件。文章还探讨了EOF作为行结束符的情况,并提供了一种使用自定义结束符的方法。
摘要由CSDN通过智能技术生成

       主要在看K&R的The C Programming Language,对于1.5节“字符输入/输出”理解不透,getchar的原理没有搞清楚,EOF的值知道是-1,但是对于

	 int c;
	while ((c = getchar()) != EOF)
       		putchar(c);

每输入一行,回车一下,会输出上一行内容,不知道什么时候才能结束。最傻的方法是,输入-1,当然程序还是没有结束。

       后来查资料,才发现对于getchar(),一般都会有两点总结,先附上。


一、getchar()的两点总结

1. getchar()是以行为单位进行存取的。

当用getchar进行输入时,如果输入的第一个字符为有效字符(即输入不是文件结束符EOF,Windows下为组合键Ctrl+Z, Unix/Linux下为组合键Ctrl+D),那么只有当最后一个输入字符为换行符'/n'(也可以是文件结束符EOF,EOF将在后面讨论)时, getchar才会停止执行,整个程序将会往下执行。

例如,上面的代码,就是自己输入时出出现的情况,每输入一行,再按回车,就会输出相应的内容。

这里不能忘了,系统输出时,还有一个”回车符“,这也是为什么我们看到新的输入提示符出现在新的一行,这是回车符的效果。从另外一点也能反应这个问题,就是书上1.5.2讲的”计算字符的个数“,我们会发现总个数是加上回车符个数的。

例如,

	int cha;
	long nc = 0;
	while ((cha = getchar()) != EOF)
	{
		putchar(cha);
		++nc;
	}
	printf("%d\n", nc);

对于上面的程序,我们可以得到下面的结果:

可以看出,最后字符的总个数为9,和上面的分析是符合的。

2. getchar()的返回值一般情况下是字符,但也可能是负值,即返回EOF。

这里要强调的一点就是,getchar函数通常返回终端所输入的字符,这些字符系统中对应的ASCII值都是非负的。因此,很多时候,我们定义

char c; 
c = getchar ( ) ;

这样就很容易出现问题因为getchar函数除了返回终端输入的字符外,在遇到Ctrl+D(Linux下)(Windows下Ctrl+Z)即文件结束符EOF时,getchar ()的返回EOF,这个EOF在函数库里一般定义为-1。因此,在这种情况下,getchar函数返回一个负值,把一个负值赋给一个char型的变量是不正确的。

为了解决这个问题,书中也提到了方法,就是定义为int类型。即为本文刚开始的程序。


二、EOF的两点总结(主要指普通终端中的EOF)

首先明确一下EOF的概念,EOF即End of File,是在stdio.h中定义的一个常量,为#define EOF (-1)  用来表示文件的结尾,当某些函数读取到文件尾时便返回EOF。另外,不是说每个文件的尾部都有一个专门的标志用来标示文件结尾,更不是说每个文件尾都有EOF,我们可以想象一下,如果我们每次读取一个字符都要判断是否到达文件尾,那样效率也太低了,那如何判断文件是否已经结束了呢?中断、异常。当我们用函数读入文件数据的时候,函数总会返回一个状态,是读取成功还是失败,那么这个状态怎么表示呢,所以就约定俗成定义一个标识符表示这个状态,就有了EOF,BOF等等。

1.EOF作为文件结束符时的情况

EOF虽然是文件结束符,但并不是在任何情况下输入Ctrl+D(Windows下Ctrl+Z)都能够实现文件结束的功能,只有在下列的条件下,才作为文件结束符。
(1)遇到 getcahr函数执行时,要输入第一个字符时就直接输入Ctrl+Z,就可以跳出getchar(),去执行程序的其他部分;
(2)在前面输入的字符为换行符时,接着输入Ctrl+Z;

(3)在前面有字符输入且不为换行符时,要连着输入两次Ctrl+Z,这时第二次输入的Ctrl+Z起到文件结束符的功能。

其实,这三种情况都可以总结为只有在getchar()提示新的一次输入时,直接输入Ctrl+Z才相当于文件结束符。

PS:对于第(3)点,是基于他人的总结,自己在windows下实践时,似乎并不能满足文件结束的功能,这点还需要研究一下。


2.EOF作为行结束符时的情况,这时候输入Ctrl+Z并不能结束getchar(),而只能引发getchar()提示下一轮的输入 。

在进行getchar()新的一行输入时,当输入了若干字符(不能包含换行符)之后,直接输入Ctrl+Z,此时的Ctrl+Z并不是文件结束符,只是引发下一轮的输入。


EOF 的作用也可以总结为:

当终端有字符输入时,Ctrl+Z产生的EOF相当于结束本行的输入,将引起getchar()新一轮的输入;

当终端没有字符输入或者可以说当getchar()读取新的一次输入时,输入Ctrl+Z,此时的EOF相当于文件结束符,程序将结束getchar()的执行。


—— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— —— ——

经过上面的分析,大概已经了解了getchar()和EOF的使用方法。其实仔细再想想,我们为什么讨论这两个问题,因为他们总是结合起来用,对于getchar()必须要有一个结束符,来结束从键盘的输入。

其实,总结自己的编程经验,当需要从键盘输入字符时,发现有时候并没有用EOF这样的结束符,而是自己定义了一个结束符,例如‘#’,这个当然要在程序中说明。例如:

	   cout<<"请输入需要加密的明文,以#作为结束符:";
	while(c != ‘#')
	{
		c = getchar();
		inBuffer[i++] = c;
	}


本文参考的文章地址:http://blog.csdn.net/lichaoandy/article/details/5525115


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值