大家好,本文主要讲的是C语言中getchar()用法的详细讲解。有兴趣的同学过来看看,如果对你有帮助记得收藏。
目录
前言getchar混淆点缓冲区引起的缓冲区问题getchar工作原理解决缓冲区引起的问题清除缓冲区解决初始混淆总结
前言
最近在重新学习C语言的时候,发现了一个严重的问题。我不能使用getchar.我不是不会用。我发现了一个很困惑的问题。可能我刚接触C语言的时候,没有把这个概念讲清楚,所以现在不理解。
getchar困惑的点
我用getchar函数输入了一串字符ABCD,然后把这串字符给了ch,然后我打印了这个ch,然后得到了一个字符a,你看到这个也没觉得有什么问题吧?当然没有什么问题,因为getchar只能读取一个字符,所以它自然只能读取A,然后在打印的时候,它自然只打印这个A。
好吧,我们继续往下看。
看到这里,不知道你有没有想到一个问题。反正这个问题困扰了我很久。
首先,通过第一个例子,我们知道getchar只能读取一个字符。
但是在这个例子中,我输入了一串字符ABCDE,按理说他只读取了一个字符,也就是这串字符中的第一个字符A,然后读取完之后给变量ch,然后判断这个ch不等于EOF。
EOF是文件结束标记,是键盘上的ctrl z。你可以自己打印出来,然后对照ASCII码检查。
很明显,当前没有ctrl z,所以条件为真,然后执行print语句。
根据我们上面的分析,那么应该打印一个字符A,对吗?令人困惑的事情发生了,它印了ABCDE!是的,完全打印出来了。
你可能经常会看到这种类似的程序,然后就习惯了,觉得应该完全打印出来。
好了,在这一点上,你是否感到困惑?为什么会这样?
那我现在就告诉你吧。原来这里面涉及到一个概念。
缓冲区
缓冲区,也称为缓存,是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,用来缓冲输入或输出的数据。这个保留的空间称为缓冲区。
那么这和我们的getchar有什么关系呢?
当然有联系。当我们调用getchar函数时,这个函数实际上是在内部完成的:
这个时候他会先从缓存中读取。读完之后,他发现缓存中没有数据。他会等待外部输入,此时光标会闪烁~
当我们在外部输入字符时,那么我们会按enter键结束,而此时我们输入的所有字符实际上直接存在于缓存中。
假设此时我输入字符ABCD,然后回车完成,然后缓冲区里就有ABCD了\ n
注意,有趣的事情来了,还有\n?哈哈,继续往下看。
缓冲区带来的问题
仔细看看,看看能不能发现我为什么不在getchar里输入字符。
其实不是我没输入字符。只是我输入完scanf的字符后,回车结束这个scanf的输入。然后奇怪的事情发生了,程序直接结束。是的,我跳过了用getchar输入字符的过程。
你觉得奇怪吗?
这就是我刚才跟你提到的\n
嗯,这个时候我调用scanf函数的时候,外部输入ABCD,然后我输入ABCD之后,我就要结束输入了,然后我们就打enter。立正!这个回车其实是一个字符,然后会和我之前输入的ABCD一起放入缓存,也就是说此时缓存中有ABCD in
让我们做一个小测试来找出答案。
看到打印出来的结果,你明白吗?
getchar工作原理
原来,当调用getchar函数时,它实际上是直接从缓冲区中读取。如果缓冲区有数据,他会直接取第一个,然后他的任务就结束了。其实在这里就是上面的scanf取了缓存中的ABCD,还剩一个10。这个10实际上是\n,是它在ASCII码中的表示。于是剩下的\n存到了缓存里,然后他这时候遇到了getchar函数,然后getchar在缓存里读取,发现:诶,还剩一个\n,我直接拿走,然后他的任务就结束了,于是就出现了他不会等待我们外部输入的情况。
那么我们能解决这个问题吗?
解决缓冲区带来的问题之清空缓存区
了解了buffer和getchar的联系之后,我们就很容易解决了。
我们只需要在getchar读取之前插入一个getchar函数,也就是说,在下一次真正的getchar读取之前,让我们先用一个getchar函数读取那个缓冲区的剩余部分\n,这样下次我们实际读取getchar时缓冲区就为空了。
既然我们已经彻底了解了getchar的工作原理,我们就回到最初的谜题。
解决最初的困惑
第一个循环:首先缓冲区清空,光标闪烁,然后等待我的输入。
我输入了一个字符A,然后继续输入结尾,所以这个时候我实际上输入了两个字符,一个字符A,一个字符\n,而且都存储在缓存里。然后当缓冲区有数据时,光标停止闪烁,getchar函数开始直接读取。然后在这个循环中,getchar函数读取一个字符A,然后给ch,然后条件表达式为真(不等于ctrl z),所以打印ch,然后打印出一个字符A。
第二个周期:此时缓冲区还剩下一个\n,光标不闪烁,getchar也不会等待外部输入。
此时getchar直接读取这个缓冲区中的\n,继续给ch,然后表达式仍然为真,所以继续打印这个ch。此时,因为ch已被替换,所以\n打印进纸且光标位置改变。
第三个周期:缓冲区为空,getchar无法读取数据,光标闪烁,getchar等待外部输入数据。
此时,我们正在向下看。
第一个周期:缓冲区为空,getchar无法读取缓冲区中的数据,于是光标闪烁,getchar等待外部输入数据。
此时,我输入了一串ABC,然后回车结束输入。这时缓冲区里有字符ABCD\n,然后getchar读取第一个字符A,然后给ch,然后条件表达式为真,打印ch,于是第一个A出来了。
第二个循环:缓冲区中还有BC \ n \ n,getchar直接读取。
此时getchar读取字符B,然后给ch,条件表达式为真。继续打印ch,然后得到AB。
第三个循环:缓冲区还有C\n,getchar直接读取。
然后同一个getchar读取C,然后给ch,然后表达式为真,ch被打印出来,然后经过这个循环得到ABC。
第四个循环:缓冲区还剩一个\n,最后打印这个\n,于是显示光标的下一行。
最后的结果是ABC。
然后我再输入ctrl Z。
所以缓冲区里有ctrl z(EOF),然后getchar读取,然后给ch,然后表达式判断条件为假,ch==EOF,于是循环跳出,程序结束。
总结
Getchar函数直接从缓冲区读取数据。如果缓冲区中有数据,它将直接读取第一个数据。如果没有数据,它会闪烁光标并等待外部输入数据。
需要注意的是,我们在别处输入的回车也会被当作已有缓冲区中的一个字符,之后getchar会直接读出,这个地方容易出错!
关于getchar()在C语言中使用的详细说明,本文到此为止。关于C语言中getchar()的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。