Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【C语言】getchar 函数的正确使用

【C语言】getchar 函数的正确使用

作者头像
全栈程序员站长
发布于 2022-11-02 08:11:16
发布于 2022-11-02 08:11:16
1.9K02
代码可运行
举报
运行总次数:2
代码可运行

目录


一、getchar 函数

从上面的介绍来看,我们要正确使用getchar函数,首先得了解什么是缓冲区。


二、缓冲区

1、什么是缓冲区

缓冲区又称为缓存,它是内存空间的一部分。

也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区。

缓冲区根据其对应的是输入设备输出设备,分为输入缓冲区和输出缓冲区。


2、为什么要存在缓冲区

我们为什么要引入缓冲区呢?

比如我们从磁盘里取信息,我们先把读出的数据放在缓冲区,计算机再直接从缓冲区中取数据,等缓冲区的数据取完后再去磁盘中读取,这样就可以减少磁盘的读写次数,再加上计算机对缓冲区的操作大大快于对磁盘的操作,故应用缓冲区可大大提高计算机的运行速度。

又比如,我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。现在您基本明白了吧,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来缓存数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。


3、缓冲区的类型

缓冲区分为三种类型:全缓冲、行缓冲和不带缓冲。

1、全缓冲 在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。

2、行缓冲 在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据

3、不带缓冲 也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。


4、缓冲区的刷新

以下四种情况会引发缓冲区刷新:

  1. 缓冲区满时;
  2. 执行 flush 语句;
  3. 执行 endl 语句;
  4. 关闭文件。

三、getchar 函数的正确使用

1、getchar 的换行问题

我们来观察下面这段代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
int main()
{ 
   
	int ch = 0;
	while ((ch = (getchar())) != EOF)
	{ 
   
		putchar(ch);
	}
	return 0;
}

我们可以看到我们每次从键盘输入一个字符并回车后,putchar输出时会自动换行,就是因为我们每次除了输入字符外,还敲了一个回车,而这个回车会被存储在缓冲区中,当我们用getchar读取字符时,会从缓冲区中依次逐个读取所有的字符(包括换行、空格、Tab),直到缓冲区中没有数据,每读取一个字符就用putchar打印一下,所以这里会自动换行。

^Z:Ctrl+Z,输入后会被认定为EOF,从而来结束循环(VS中有些时候要重复按三次才会结束循环,其他编译器都是按一次)。


2、getchar 与 scanf 的混合使用

我们来观察下面这段代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
int main()
{ 

char password[20] = { 
 0 };
printf("请输入密码:>");
scanf("%s", password);
printf("请确认密码(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{ 

printf("确认成功\n");
}
else
{ 

printf("确认失败\n");
}
return 0;
}

我们可以看到程序并没有等待我们输入Y/N来确认密码,而是直接结束,原因就是我们缓冲区中存放的是abcdef\n,而scanf函数是遇到空格、换行符(\n)、Tab时结束,所以\n并没有被读取走,而是继续留在了缓冲区中,而当getchar读取数据时发现缓冲区中并不为空,所以直接读取了\n,然后判断if条件,结束程序,而不会等待我们输入Y/N。


那么要如何避免这种情况发生呢?有两种方法: 法一:在scanf后面加一个getchar(不推荐)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
int main()
{ 

char password[20] = { 
 0 };
printf("请输入密码:>");
scanf("%s", password);
getchar();  //读取剩下的\n
printf("请确认密码(Y/N):>");
int ch = getchar();
if (ch == 'Y')
{ 

printf("确认成功\n");
}
else
{ 

printf("确认失败\n");
}
return 0;
}

我们在scanf函数后面加上一个getchar函数,用于清空缓冲区里面多余的\n,但是这种方法有弊端,不推荐使用,具体弊端如下:

如图:我们从键盘输入abcd ef,我们可以看到,程序并没有等待我们输入Y/N,而是直接执行if语句,这是因为 scanf函数遇到空格、换行符(\n)、Tab时会停止读取,所以缓冲区中剩下的字符是_ef\n,一次getchar无法清空缓冲区。所以说,法一只能解决一部分情况,想要彻底解决scanf缓冲区残留的问题需要用到法二。


法二:在scanf后面加 while( getchar() != ‘\n’) 语句(推荐)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
#include<stdio.h>
int main()
{ 

char password[20] = { 
 0 };
printf("请输入密码:>");
scanf("%s", password);
getchar();  //读取剩下的\n
printf("请确认密码(Y/N):>");
while (getchar() != '\n')
{ 

;
}
int ch = getchar();
if (ch == 'Y')
{ 

printf("确认成功\n");
}
else
{ 

printf("确认失败\n");
}
return 0;
}

程序中的while( getchar() != ‘\n’)语句会不断读取缓冲区中的字符,直到把\n读取走,从而达到清空缓冲区的目的。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180276.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
【C语言初阶篇】scanf和getchar中缓存区的概念!
🎬 鸽芷咕:个人主页 🔥 个人专栏:《C语言初阶篇》 《C语言进阶篇》
鸽芷咕
2023/12/25
3610
【C语言初阶篇】scanf和getchar中缓存区的概念!
c语言中putchar的用法举例_putchar和getchar
getchar() 和 putchar() 是一对字符输入/输出函数. getchar()不带任何参数,他从输入序列中返回下一个字符。例如,下面的语句读取下一个字符输入,并把该字符的值赋给变量ch:
全栈程序员站长
2022/11/02
1.2K0
getchar的使用
1.从缓冲区读走一个字符,相当于清除缓冲区 2.前面的scanf()在读取输入时会在缓冲区中留下一个字符’\n’(输入完s[i]的值后按回车键所致),所以如果不在此加一个 getchar()把这个回车符取走的话,gets()就不会等待从键盘键入字符,而是会直接取走这个“无用的”回车符,从而导致读取有误 3. getchar()是在输入缓冲区顺序读入一个字符(包括空格、回车和Tab) getchar()使用不方便,解决方法: (1)使用下面的语句清除回车: while(getchar()!=’\n’); (2)用getche()或getch()代替getchar(),其作用是从键盘读入一个字符(不用按回车),注意要包含头文件<conio.h> 4. getchar()是stdio.h中的库函数,它的作用是从stdin流中读入一个字符,也就是说,如果stdin有数据的话不用输入它就可以直接 读取了,第一次getchar()时,确实需要人工的输入,但是如果你输了多个字符,以后的getchar()再执行时就会直接从缓冲区中读 取了。 实际上是 输入设备->内存缓冲区->程序getchar 你按的键是放进缓冲区了,然后供程序getchar 你有没有试过按住很多键然后等一会儿会滴滴滴滴响,就是缓冲区满了,你后头按的键没有存进缓冲区. 键盘输入的字符都存到缓冲区内,一旦键入回车,getchar就进入缓冲区读取字符,一次只返回第一个字符作为getchar函数的值,如果 有循环或足够多的getchar语句,就会依次读出缓冲区内的所有字符直到’\n’.要理解这一点,之所以你输入的一系列字符被依次读出 来,是因为循环的作用使得反复利用getchar在缓冲区里读取字符,而不是getchar可以读取多个字符,事实上getchar每次只能读取一 个字符.如果需要取消’\n’的影响,可以用getchar();来清除,这里getchar();只是取得了’\n’但是并没有赋给任何字符变量,所以不 会有影响,相当于清除了这个字符.还要注意的是这里你在键盘上输入ssss看到的回显正是来自于getchar的作用,如果用getch就看不
全栈程序员站长
2022/07/22
9440
getchar的使用
scanf与getchar连用注意事项
在用scanf输入后,用回车键换行,且下一语句为getchar时,getchar会被回车键(相当于'/n')使用,因为scanf不能读取回车键、空格键等。
秦jh
2024/01/19
1810
C Primer Plus(三)
在计算机编程过程中,输入和输出是绕不开的知识点,如输入输出设备、数据的输入输出、以及输入输出函数(I/O 函数)等等。I/O 函数(如 printf()、scanf()、getchar()、putchar() 等)负责把信息传送到程序中。要注意的是输入/输出函数并不是 C 定义的一部分,C 把开发这些函数的任务留给编译器的实现者来完成。在实际应用中,UNIX 系统中的 C 实现为这些函数提供了一个模型。ANSI C 库则吸取成功的经验,把大量 UNIX I/O函数囊括其中。
1ess
2021/11/01
5560
【C语言】输入/输出函数详解
在C语言中,输入/输出操作是通过标准库函数来实现的。这些函数分为两类:标准输入输出函数和文件输入输出函数。为了使用这些函数,我们需要包含头文件stdio.h,即在代码的开头加入:
LuckiBit
2024/12/11
3080
【C语言】输入/输出函数详解
分支和循环语句(1)
控制语句用于控制程序的执行流程,以实现程序的各种结构方式(C语言支持三种结构:顺序结构、选择结构、循环结构),它们由特定的语句定义符组成,C语言有九种控制语句,可分成以下三类:
waves浪游
2024/01/23
1880
分支和循环语句(1)
新手C语言学习(1)
        在昨天的c语言学习中所发现值得积累的东西。         首先,在vs2017中,无法识别scanf困扰了我一下,于是我去网上搜索解决办法,借鉴这位老哥一下(链接)就是依次点开项目-属性-c/c+±预处理器,然后_CRT_SECURE_NO_WARNINGS输入,应用就完事了。         归咎其原因,就是微软认为scanf不安全,于是在此之前我又在网上搜,说把scanf改成scanf_s就可以,我也就没仔细了解,反正在后面加了个_s倒是不报错了,结果在运行代码的时候,虽然可以运行,但却一直会有个弹窗
半生瓜的blog
2023/05/12
3300
新手C语言学习(1)
C语言入门(循环和分支语句、goto语句)
比如:输入1,打印星期一;输入2,打印星期二……输入7,打印星期天。这种如果用if...else if...else的形式就过于复杂了,这种类型就适用于switch语句。
see.
2024/06/04
1570
C语言入门(循环和分支语句、goto语句)
【C语言】getchar()函数缓冲区
目录 前言😄 gethcar()函数的介绍🔥 缓冲区 结束语 ---- ---- ✨专栏:《C语言从0到1》 ✨送给各位的一句话:种一棵树最好的时间是十年前,其次是现在 ✨说明:无论如何,当我们下定决心的时候,那就是来得及的,你只管努力,剩下的交给天意! ---- 前言😄 大家好啊,由于之前有关C语言的博客写的比较少,不够详细,加之较少的时间写博客,但是我会尽己所能,把每一篇博客写好,帮助自己复习的同时,我也希望能够帮助到大家,让我们一起努力学习吧。接下去,我会陆续更新并且完善关于专栏《C语言
平凡的人1
2022/11/15
1.3K0
【C语言】getchar()函数缓冲区
C语言 getchar()原理及易错点解析
这个问题转载自n_s_X14,但是作者在文章最后留了一个问题,现在在这里给大家解释一下原因。
全栈程序员站长
2022/11/02
1.5K0
C语言 getchar()原理及易错点解析
C语言getchar的用法_getchar的用法
当我们执行以上程序,会一直读取字符并且换行,以下做出解释: 1、为什么会自动换行? 当我们在键盘上敲入a的时候,getchar并没有获取,而是在我们敲回车以后才会进行读取 这个时候我们输入的其实是两个字符 一个是’a’,另一个是’\n’ 2、如何中止这个程序? 输入Ctrl+Z进行中止,这个时候我们的输入会有EOF的标志 3、当我们进行输入的时候,真实的情况是什么样的? 当我们输入的时候并不是键盘直接到getchar,而是中间有一个输入缓冲区,getchar一直在等待缓冲区里的内容,正是有了缓冲区的存在,才会出现有1的问题 4、我们如何清空缓冲区以免对后续操作造成影响呢? 我们作出以下研讨:
全栈程序员站长
2022/11/02
1.7K0
C语言getchar的用法_getchar的用法
[C语言]分支循环语句
2. 循环执行语句: do while 语句、 while 语句、 for 语句;
IT编程爱好者
2023/04/12
8240
[C语言]分支循环语句
c语言getchar()的用法_c=getchar()
该函数以无符号 char 强制转换为 int 的形式返回读取的字符,如果到达文件末尾或发生读取错误,则返回 EOF(-1)。所以 getchar() 函数返回值要用 int 整型变量来存储
全栈程序员站长
2022/11/02
8.1K0
c语言getchar()的用法_c=getchar()
部分C语言语句
C++语言语句 分支语句 if语句 //单分支 if(表达式) 语句; //若表达式为真,则执行该语句,否则什么都不执行 if(表达式) 语句1; else 语句2; //若表达式为真,则执行语句1,否则执行语句2 //多分支 if(表达式1) 语句1; else if(表达式2) 语句2; else 语句3; //若表达式1为真则执行语句1,另外如果表达式2成立则执行语句2 //否则执行语句3,以表达式1为先,三个语句只可执行一个 //只有表达式1为假,后
暮云
2022/10/05
6210
部分C语言语句
一文带你读懂C/C++语言输入输出流与缓存区
有没有发现,基本上所有的C语言入门书籍,或者是我们的教程里面,第一个C语言程序实体,都是“Hello Word!”;我不知道这是不是行业的“潜规则”,总之,它把无数的程序员带进了计算机的世界,步入了代码的大坑里,所以你好,世界!
李肖遥
2020/06/23
1.3K0
C 标准库基础 IO 操作总结
打开文件其实就是在操作系统中分配一些资源用于保存该文件的状态信息及文件的标识,以后用户程序可以用这个标识做各种读写操作,关闭文件则释放占用的资源。
用户3105362
2021/02/04
1K0
getchar()和scanf()混合使用的坑
最近在混合使用 getchar() 和 scanf() 的时候遇到一个坑,现在记录一下。
nnngu
2020/07/03
1.1K0
『C语言』字符串的输入gets()和输出puts()
对于这些输入函数和输出函数我们还是有必要知道的,因为可以说在编写程序的时候用到的最多的就是输入函数和输出函数了。
謓泽
2022/12/30
2.7K0
『C语言』字符串的输入gets()和输出puts()
【C语言】题集 of ⑤
🚀write in front🚀   📝个人主页:打打酱油desu_泽En_CSDN博客 🆔本文由 泽En 原创 CSDN首发🐒 如需转载还请通知⚠ 🏅2021年度博客之星物联网与嵌入式开发TOP5→作者周榜56→总排名3255🏅  🎁欢迎各位→点赞👍 + 收藏⭐️ + 留言📝​ 📣系列专栏:【C】题目_打打酱油desu-CSDN博客 💬总结:希望你看完之后,能对你有所帮助,不足请指正!共同学习交流 🖊 ✉️我们并非登上我们所选择的舞台,演出并非我们所选择的剧本 ♐  目录 🚀write
謓泽
2022/12/12
6200
【C语言】题集 of ⑤
相关推荐
【C语言初阶篇】scanf和getchar中缓存区的概念!
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验