C语言中scanf函数详解「建议收藏」

C语言中scanf函数详解「建议收藏」scanf函数  上一节中我们讨论了,如何将整数,浮点数,字符串打印到屏幕上去。既然有输出,怎么能没有输入呢?这一节中,我们来介绍与printf相反的scanf函数。  scanf的功能是将键盘输入的字符串转换成整数、浮点数、字符或字符串。1.scanf函数的使用公式scanf是一个变参函数。(参数的数量和类型不确定)scanf的第一个参数是字符串。scanf的第一个参数是需要输入的字符串以及需要被读取的占位符。scanf的后续参数,是依次被读取并赋值的变量地址。占位符的类型和数量需要与

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

scanf函数

  上一节中我们讨论了,如何将整数,浮点数,字符串打印到屏幕上去。既然有输出,怎么能没有输入呢?这一节中,我们来介绍与printf相反的scanf函数。

  scanf的功能是将键盘输入的字符串转换成整数、浮点数、字符或字符串。

1. scanf函数的使用公式

  1. scanf是一个变参函数。(参数的数量和类型不确定)
  2. scanf的第一个参数是字符串。
  3. scanf的第一个参数是需要输入的字符串以及需要被读取的占位符。
  4. scanf的后续参数,是依次被读取并赋值的变量地址。
  5. 占位符的类型和数量需要与后续的参数类型和数量对应。
#include <stdio.h>
int main()
{
    short s;
    int n;
    long l;
    float f;
    double df;
    scanf("s=%hd n=%d l=%ld f=%f df=%lf", &s, &n, &l, &f, &df);
    printf("%d %d %d %f %f\n", s, n, l, f, df);
    return 0;
}

Jetbrains全家桶1年46,售后保障稳定

  这里读者不必理解如何使用指针,只需要记住以下两条简单的规则:

  1. 如果用scanf()读取基本变量类型的值,在变量名前加一个&。
  2. 如果用scanf()把字符串去读到字符数组中,不要使用&。

scanf

  可以发现scanf是printf的逆向过程。注意,键盘输入的时候,必须要和scanf的第一个参数的字符串对应。也就是说,对于上面的代码输入必须是:

s=1 n=2 l=3 f=4.5 df=6.7

  以下几个是错误的示范

1 2 3 4.5 6.7
不一致,错误
s=1n=2l=3f=4.5df=6.7
由于scanf的第一个参数是"s=%hd n=%d l=%ld f=%f df=%lf",带有空格。
输入漏掉了空格,错误。
当然,如果scanf的第一个参数是"s=%hdn=%dl=%ldf=%fdf=%lf",那么这样就是正确的。
s=1,n=2,l=3,f=4.5,df=6.7
错误,由于scanf的第一个参数是用空格分隔的。

  视频演示

https://cpl.zhoushengjie.com/11_scanf/


TIPS:

  如果你使用的是较新版本的Visual Studio,scanf这类函数会被认为是不安全的,编译器会抛出C4996错误,并建议你使用别的安全函数替代。

  但是,目前我们并不想引入并讨论这一类安全函数。请将_CRT_SECURE_NO_WARNINGS加入预定义字符串,屏蔽不安全函数错误。

C4996

  添加步骤方式如下:

  1. 解决方案下,工程点右键,进入属性。
  2. 展开C/C++,选择预处理器。
  3. 点击预处理器定义【编辑】。
  4. 将_CRT_SECURE_NO_WARNINGS加入预处理定义。

  视频演示

https://cpl.zhoushengjie.com/11_scanf/


2. 占位符

  scanf的占位符规范和printf类似,但有些不同。请使用的时候,不要混淆了。scanf的占位符组成如下。

  1. 一个可选的最大字段宽度,用一个正的十进制整数表示。
  2. 一个可选的长度指定符
  3. 必须的转换操作。
转换操作 长度指定符 参数类型
d hh char *
d h short int *
d int *
d l long *
d ll long long *
u hh unsigned char *
u h unsigned short int *
u unsigned int *
u l unsigned long *
u ll unsigned long long *
f float *
f l double *
f L long double *
c char *
s char *

3. 示例

    short s;
    scanf("%hd", &s);
    int n;
    scanf("%d", &n);
    long l;
    scanf("%ld", &l);
    long long ll;
    scanf("%lld", &ll);
    unsigned short us;
    scanf("%hu", &us);
    unsigned int un;
    scanf("%u", &un);
    unsigned long ul;
    scanf("%lu", &ul);
    unsigned long long ull;
    scanf("%llu", &ull);
    float f;
    scanf("%f", &f);
    double df;
    scanf("%lf", &df);
    long double ldf;
    scanf("%Lf", &ldf);

4.scanf与printf的不同

  1. printf的后续参数不要加&,而scanf由于需要一个指针,所以需要加&。

  2. printf的参数由于比int小的变量会升级为int,这样数据仍然是完整的。仅比int大的需要额外指明长度指示符。

  3. scanf会将数据填充到对应的变量里去,必须指明被填充的对象是什么,用int来填充char很显然是错误的,所以必须明确指定长度指示符。例如%hhd用于char,%hd用于short。

5. 检查是否使用了错误的占位符

  如果你使用了错误的占位符,得益于新版的编译器,你可以在warning中看到这些提示。

#include <stdio.h>
int main()
{
    char c;
    scanf("%d", &c);
    short s;
    scanf("%d", &s);
    int n;
    scanf("%d", &n);
    long l;
    scanf("%d", &l);
    long long ll;
    scanf("%d", &ll);
    return 0;
}

warn

  根据提示,更正为如下即可。

#include <stdio.h>
int main()
{
    char c;
    scanf("%hhd", &c);
    short s;
    scanf("%hd", &s);
    int n;
    scanf("%d", &n);
    long l;
    scanf("%ld", &l);
    long long ll;
    scanf("%lld", &ll);
    return 0;
}

6. scanf参数必须用&的原因

void setToZero(int a, int b)
{
	a = 0;
	b = 0;
	//  当函数不需要返回值的时候,可以把返回值类型设置为void
}

int main()
{
	int a, b;
	a = 2;
	b = 3;
	setToZero(a, b);
	printf("%d %d\n", a, b);
	return 0;
}

  在这段代码中,变量a,b分别在main,和add变量中,那么,main中的a和b与add中的a和b是同一个变量吗?

  显然不是,函数调用的时候,是把main中a,b的值,传递给了add中的a,b。
add中无论如何修改a,b。无法影响到main中的a,b。这里有个技巧,{}是变量作用域,在不同{}内的同名变量,是不相干的。

  既然不管是否同名,用传递值的办法setToZero都无法影响main中的变量。

  那么回到scanf中,它也无法影响到scanf外的变量,那是怎样修改scanf外面的变量的呢?

  答案是,使用指针。指针就是一个变量的地址,有了这个地址就能找到这个变量,并且修改它的值。因此,scanf的参数,都用了&。传递的类型,都是指针类型。

scanf_star

在这里插入图片描述

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

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

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • java hibernate 实现按条件删除多对象[通俗易懂]

    java hibernate 实现按条件删除多对象[通俗易懂]背景:在hibernate应用中,需要实现按条件删除功能场景:在方法中传入泛型对象,构建HQL语句思路:遍历对象属性,如果有值,表明该字段是删除条件,用它构建删除HQL。具体做法是遍历对象对象的所有get方法,然后通过方法反射获取到对象的值。然后再判断值是否为空,从而组装HQL语句使用例子:publicclasstestH{publicstaticvoidmain(String[]args){Sessionsession=sessi

    2022年6月16日
    30
  • PyCharm的几个使用技巧(持续更新)[通俗易懂]

    PyCharm的几个使用技巧(持续更新)[通俗易懂]目录引言1、轻松加注释2、让代码自动缩进3、快速自定义文件4、一键全局格式化5、轻松查找与替换6、关闭波浪线引言PyCharm是个十分强大的Python编辑器,笔者在日常的工作中学到了很多该IDE的使用技巧,有的是从别人那里学到的,有的是自己学习的。you  以下将介绍几个简单的PyCharm使用技巧。以windows系统中的PyCharm使用为例。1、轻松加注释多行注释:CTRL+/…

    2022年8月25日
    3
  • 一个Scrapy爬虫实例

    一个Scrapy爬虫实例目录Scrapy是啥Scrapy的安装实例:爬取美剧天堂new100:(1)创建工程:(2) 创建爬虫程序(3) 编辑爬虫(4)设置item模板:(5) 设置配置文件(6)设置数据处理脚本:(7)运行爬虫Scrapy是啥scrapy是一个使用python编写的开源网络爬虫框架。这里的框架实际上就是应用程序的骨架,是一个半成品,框架能够保证程序结构风格统一。Scrapy的安装pipinstallScrapy。但在此之前要先安装几个包:在cmd中运行以下语句:(1) pipinstallwh

    2022年6月26日
    24
  • K8s基本概念入门_k8s菜鸟教程

    K8s基本概念入门_k8s菜鸟教程序言    没等到风来,绵绵小雨,所以写个随笔,聊聊k8s的基本概念。    k8s是一个编排容器的工具,其实也是管理应用的全生命周期的一个工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非常的方便,而且可以做到故障自愈,例如一个服务器挂了,可以自动将这个服务器上的服务调度到另外一个主机上进行运行,无需进行人工干涉。那么,问题来了,要运维何用?    k8s可以更快的更新新版

    2022年10月22日
    0
  • Nginx转发ssh服务「建议收藏」

    Nginx转发ssh服务「建议收藏」一、需求当前置机需要转发内网主机的ssh端口号,方便外网直连服务器。二、nginx配置注:与events,http同级,配置stream即可events{worker_connections1024;accept_mutexon;}stream{ upstreamssh{ server10.11.4.78:22;#这里IP是虚拟机的,对应虚拟机的IP+Port } server{ listen9028;#外层通信需要的tc

    2022年10月18日
    0
  • 因果图法_软件测试因果图怎么画

    因果图法_软件测试因果图怎么画一、黑盒测试:是一种常用的软件测试方法,它将被测软件看作一个打不开的黑盒,主要根据功能需求设计测试用例,进行测试。几种常用的黑盒测试方法和黑盒测试工具有,等价类划分法、边界值分析法、因果图法、决策表法。在实际运用中要选择合适的方法。二、因果图法:等价类划分法和边界值分析方法都是着重考虑输入条件,如果程序输入之间没有什么联系,采用等价类划分和边界值分析是一种比较有效的方法。如果输入之间有关系,例…

    2022年4月19日
    70

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号