【C】getchar函数、EOF与SUB

什么是getchar函数?

        getchar函数是一个输入函数,包含在stdio.h头文件中。它的作用是从键盘输入缓冲区中依次读取字符,每次读取一个,然后将该字符的ASCII码值作为整型返回若读取出错,则返回EOF(即文件结束符,值为-1)。该函数无参数,一般使用形式为getchar()。

什么是输入缓冲区?

        输入缓冲区是用来暂存用户从键盘输入字符的内存区。getchar函数用到的缓冲区是行缓冲区,也就是以换行符\n作为结束标志的缓冲区。

        当程序调用getchar函数时,若此时输入缓冲区为空,则程序暂停,等待用户输入字符,直到用户输入了一个换行符\n(即enter按键)为止,此时将用户输入的所有字符存放到缓冲区中(包括最后的换行符\n)。然后getchar函数开始读取第一个字符的ASCII码值,并将此值作为函数值返回。下一次调用getchar函数时,getchar函数读取缓冲区中第二个字符的ASCII码值…直到缓存区的所有字符都被读取了一遍(缓冲区最后的\n也会被读取)。此时再调用getchar函数时,程序又暂停,等待用户输入…

什么情况下getchar函数读取出错?

        当getchar函数读取到一个EOF(键盘输入为Ctrl+Z)时,读取出错,此时返回EOF(即-1)。

什么是EOF?

        EOF即end of file的缩写,是一个特殊的字符,称为文件结束符。类似其他字符,EOF本质上也是一个整型值,但EOF没有ASCII码,它的值为-1。在终端用键盘输入EOF的方法是Ctrl+Z,但应注意不是所有的Ctrl+Z都代表EOF。

为什么不是所有的Ctrl+Z输入都代表EOF?

        Ctrl+Z在终端输入时显示为^Z,这个输入可以代表两个字符,一是ASCII码为26的控制字符SUB,另一个是文件结束符EOF。判断其到底代表哪个字符要看它在输入缓冲区中的位置,若它在输入缓冲区的第一个字符,就代表EOF。否则代表替代字符SUB。

什么是替代字符SUB?

        (上文中的方块符号在本文中会显示为␚,因此上文以图片形式放出。)

实例

int main()
{
	int i;
	char ch;
	for (i = 1, ch = getchar(); ch != EOF; i++, ch = getchar()) //ch == EOF时跳出循环
	{
		printf("%d", i);
		printf("%c", ch);
	}
	return 0;
}

        输入a、b、c、Ctrl+Z、Enter五个字符,运行结果如下:

程序执行了四次循环,并在第四次打印了4␚。显然,此处不在首位的Ctrl+Z被识别为了替代字符。执行逐过程调试并监视ch的值,也可以印证ch在第四次循环中被赋值为␚:

应注意后本来还有一个字符\n,本应执行第五次循环并打印5\n,但结果没有进入第五次循环,而是在第四次循环结束后等待用户输入新的字符。这说明getchar函数在读取到␚后,清空了输入缓冲区。再次调用getchar函数时需要重新从键盘输入

        输入Ctrl+Z、a、b、c、Enter五个字符,运行结果如下:

此处的Ctrl+Z在首位,因此被识别为了EOF。ch被赋初值为EOF,未满足循环条件,程序直接结束。在逐过程调试中监视ch的值可以看到,ch的初值为-1:

         将for循环的循环条件表达式修改一下:

int main()
{
	int i;
	char ch;
	for (i = 1, ch = getchar(); ch != '\x1a'; i++, ch = getchar()) //ch == SUB时跳出循环
	{
		printf("%d", i);
		printf("%c", ch);
	}
	return 0;
}

        此时再输入Ctrl+Z、a、b、c、Enter五个字符,运行结果如下:

输入缓冲区的首个字符EOF后还有4个字符,本应继续在后四次循环中将后四个字符依次赋给ch,打印2a3b4c5\n,但结果并非如此。这说明getchar函数在读取EOF后,也清空了输入缓冲区。再次调用getchar函数时需要重新从键盘输入

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值