“C语言“——scanf()、getchar() 、putchar()、之间的关系

2023-12-26 05:45

本文主要是介绍“C语言“——scanf()、getchar() 、putchar()、之间的关系,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

scanf函数说明

scanf函数是对来自于标准输入流的输入数据作格式转换,并将转换结果保存至format后面的实参所指向的对象。

而const char*format 指向的字符串为格式控制字符串,它指定了可输入的字符串以及赋值时转换方法。

简单来说给一个打印格式(输入数据格式),scanf函数会将打印数据格式的结果转换放到后面的实参变量当中。

比如下面的代码

#include<stdio.h>
int main()
{int a = 0;char ch = 0;double b = 0.0;scanf("%d %c %lf", &a, &ch, &b);printf("%d %c %lf", a, ch, b);return 0;
}

但scanf函数有一个缺点,就是scanf读取不了空格和回车等字符,当scanf读到这两个字符时,scanf会读取失败返回EOF,如果匹配错误也会读取失败返回EOF(比如应该是%d的数据转换到了char实参变量当中)。

EOF

EOF全名是:End of File 在<stdio.h>头文件中被定义为负值,即-1。

EOF的值不同编译器下值不同,在VS2019是-1 

如果没有将头文件<stdio.h>包含到程序中,那么EOF就没有定义,程序不能编译和运行。

getchar和putchar

putchar的返回值是int,因为字符在程序存储的是ASCII码值,而且putchar只能打印字符,不能打印字符串,就是配合getchar()使用的。如果putchar成功获取了字符就返回所写字符,失败就返回EOF。

#include<stdio.h>
int main()
{putchar('a');putchar('b');putchar('c');return 0;
}

getchar返回也是int,参数是void,可有可无,getchar是从标准输入流读取字符(空格 回车都可以读取)并将其返回,如果读取失败就返回EOF。 

比如

#include<stdio.h>
int main()
{int ch;while ((ch = getchar()) != EOF){putchar(ch);}return 0;
}

getchar如果缓冲区没有字符,getchar会等待我们的输入且摁下回车键才会打印在屏幕上。

配合putchar使用。

 按下回车键后才在屏幕上输出对应字符。

 ctrl+Z是将程序结束掉,退出了程序终止了代码循环。

crtl+Z相当于EOF。

 为什么按回车键才会将字符输出到屏幕上呢?

 C语言的输入输出一般会将读入的字符以及待输出的字符暂时保存在缓存中(缓冲区),当达到以下条件才进行实际的输入输出操作。

1.缓存已满 2.输入换行符(\n)  3.立即输出

对应方式称为1.全缓冲 2.行缓冲 3,无缓冲

键盘输入的内容不会直接给cpu处理打印在屏幕上 而是交给缓存 提高cpu运行效率。

getchar与scanf的关系

我们根据下图代码来分析getchar和scanf之间的关系

#include<stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);printf("请确认密码正确Y/N:>");char ch = 0;scanf("%c", &ch);if ('Y' == ch){printf("密码正确\n");}else{printf("密码错误\n");}return 0;
}

 当程序运行时,我们刚输入完密码程序直接结束了,都没有确定密码的正确性,这是为什么呢?

当我们输入密码摁下回车键时,在缓冲区输入了1234\n,回车键相当于换行等于转义字符\n

第一个scanf读取了1234 第二个scanf读取了\n 直接填满了两个scanf的嘴巴,因此直接程序结束

并且结果为密码错误,当我们输入完1234摁下回车键那刻\n也被载入到了缓冲区,第二个scanf

定睛一看缓冲区有内容直接就读取走了。

解决办法 

 这时我们就要请出getchar给scanf擦屁股了,因为getchar能读取回车 空格等字符。

#include<stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);printf("请确认密码正确Y/N:>");char ch = 0;getchar();scanf("%c", &ch);if ('Y' == ch){printf("密码正确\n");}else{printf("密码错误\n");}return 0;
}

但如果有人在设置密码时写入了空格,而且scanf读取不了空格和回车字符,这时还是会出现代码判断错误导致运行结果错误。

我们直接用while循环搞一个一劳永逸的解决方案

直接使用循环清空缓冲区的空格 回车等字符

#include<stdio.h>
int main()
{char password[20] = { 0 };printf("请输入密码:>");scanf("%s", password);printf("请确认密码正确Y/N:>");char ch = 0;while ((getchar()) != '\n'){;}
//以下两种写法都okscanf("%c",&ch);//ch=getchar();if ('Y' == ch){printf("密码正确\n");}else{printf("密码错误\n");}return 0;
}

 关系

输入b后摁下回车键形成\n

缓冲区载入的就是b\n

第一个scanf读取b 第二个scanf读取\n  因此程序结束语在第三行

输入a\n

scanf读取a getchar读取\n putchar输出a 

 输入a\n 第一个scanf读走a  getchar读走\n

第二个scanf正常使用再次输入b\n  putchar在下一行输出b

scanf读走as \nbxx是putchar读取的   a是第二个scanf读取的后面还有个\n

所以程序结束语在第4行。

总结

如果scanf输入过程中遇到空格 回车键等字符,scanf自己处理不了的读取字符时,就用getchar来解决,如果有多个处理不了的特殊字符就用while循环来处理(scanf处理不了的空格 回车键等特殊字符),配合getchar和putchar来给scanf的正常使用(擦屁股)。

这篇关于“C语言“——scanf()、getchar() 、putchar()、之间的关系的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/538309

相关文章

Tomcat版本与Java版本的关系及说明

《Tomcat版本与Java版本的关系及说明》:本文主要介绍Tomcat版本与Java版本的关系及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Tomcat版本与Java版本的关系Tomcat历史版本对应的Java版本Tomcat支持哪些版本的pythonJ

Vue中组件之间传值的六种方式(完整版)

《Vue中组件之间传值的六种方式(完整版)》组件是vue.js最强大的功能之一,而组件实例的作用域是相互独立的,这就意味着不同组件之间的数据无法相互引用,针对不同的使用场景,如何选择行之有效的通信方式... 目录前言方法一、props/$emit1.父组件向子组件传值2.子组件向父组件传值(通过事件形式)方

C语言中的数据类型强制转换

《C语言中的数据类型强制转换》:本文主要介绍C语言中的数据类型强制转换方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C语言数据类型强制转换自动转换强制转换类型总结C语言数据类型强制转换强制类型转换:是通过类型转换运算来实现的,主要的数据类型转换分为自动转换

利用Go语言开发文件操作工具轻松处理所有文件

《利用Go语言开发文件操作工具轻松处理所有文件》在后端开发中,文件操作是一个非常常见但又容易出错的场景,本文小编要向大家介绍一个强大的Go语言文件操作工具库,它能帮你轻松处理各种文件操作场景... 目录为什么需要这个工具?核心功能详解1. 文件/目录存javascript在性检查2. 批量创建目录3. 文件

C语言实现两个变量值交换的三种方式

《C语言实现两个变量值交换的三种方式》两个变量值的交换是编程中最常见的问题之一,以下将介绍三种变量的交换方式,其中第一种方式是最常用也是最实用的,后两种方式一般只在特殊限制下使用,需要的朋友可以参考下... 目录1.使用临时变量(推荐)2.相加和相减的方式(值较大时可能丢失数据)3.按位异或运算1.使用临时

使用C语言实现交换整数的奇数位和偶数位

《使用C语言实现交换整数的奇数位和偶数位》在C语言中,要交换一个整数的二进制位中的奇数位和偶数位,重点需要理解位操作,当我们谈论二进制位的奇数位和偶数位时,我们是指从右到左数的位置,本文给大家介绍了使... 目录一、问题描述二、解决思路三、函数实现四、宏实现五、总结一、问题描述使用C语言代码实现:将一个整

Python实现PDF与多种图片格式之间互转(PNG, JPG, BMP, EMF, SVG)

《Python实现PDF与多种图片格式之间互转(PNG,JPG,BMP,EMF,SVG)》PDF和图片是我们日常生活和工作中常用的文件格式,有时候,我们可能需要将PDF和图片进行格式互转来满足... 目录一、介绍二、安装python库三、Python实现多种图片格式转PDF1、单张图片转换为PDF2、多张图

C语言字符函数和字符串函数示例详解

《C语言字符函数和字符串函数示例详解》本文详细介绍了C语言中字符分类函数、字符转换函数及字符串操作函数的使用方法,并通过示例代码展示了如何实现这些功能,通过这些内容,读者可以深入理解并掌握C语言中的字... 目录一、字符分类函数二、字符转换函数三、strlen的使用和模拟实现3.1strlen函数3.2st

Go语言中最便捷的http请求包resty的使用详解

《Go语言中最便捷的http请求包resty的使用详解》go语言虽然自身就有net/http包,但是说实话用起来没那么好用,resty包是go语言中一个非常受欢迎的http请求处理包,下面我们一起来学... 目录安装一、一个简单的get二、带查询参数三、设置请求头、body四、设置表单数据五、处理响应六、超

C语言中的浮点数存储详解

《C语言中的浮点数存储详解》:本文主要介绍C语言中的浮点数存储详解,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、首先明确一个概念2、接下来,讲解C语言中浮点型数存储的规则2.1、可以将上述公式分为两部分来看2.2、问:十进制小数0.5该如何存储?2.3 浮点