当前位置: 首页 > news >正文

【C语言学习】scanf函数

一、定义与基本用法

scanf英文名全称scan format,即格式化扫描的意思,他的基本用法是读取用户的键盘输⼊,存给变量。它与printf函数的关系可以用以下图表示:
在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int score = 0;printf("请输入成绩:");scanf("%d", &score);printf("成绩是:%d\n", score);return 0;
}

运行结果:
在这里插入图片描述
程序运行到scanf语句时,会停下来,等待用户从键盘输入相应数值。用户输⼊数据、按下回⻋键后,scan函数就会处理用户的输入,存入变量。它的语法跟printf函数类似,使用时也需要包含头文件<stdio.h>。
由于scanf函数传递的不是值,而是地址,因此,变量的前面要加上&(取地址,如果变量是指针,则不需要加)。
格式化字符串中可以有多少个占位符,对应的就会有多少个变量,例如:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int i, j;float x, y;scanf("%d%d%f%f", &i, &j, &x, &y);printf("i=%d, j= %d, x=%f, y=%f\n", i, j, x, y);return 0;
}

运行结果:
在这里插入图片描述
上述代码中,格式字符串%d%d%f%f ,分别表示输入的前两个是整数,后两个是浮点数。
scanf函数处理数值占位符时,会自动过滤空白字符,包括空格制表符、换行符等。所以,输⼊的数据之间,有⼀个或多个空格不影响scanf函数解读数据,用户使用回车键,将输入分成几行,也不影响解读。
scanf函数在解读用户输入时,会从上⼀次解读遗留的第⼀个字符开始,直到读完缓存,或者遇到第⼀个不符合条件的字符为止。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int x = 0;float y = 0.0;scanf("%d", &x);scanf("%f", &y);printf("x=%d y=%f\n", x, y);return 0;
}

运行结果:
在这里插入图片描述
上述代码中,scanf函数第一次读取用户输⼊时,%d占位符会忽略开头的空格,从-处开始获取数据,读取到-13停下来,因为后⾯的.不属于整数的有效字符。这就是说,占位符%d会读到-13,打印出来的结果就是x=-13。
第⼆次调用scanf函数,就会从上一次停下来的地方继续往下读取。这⼀次读取的首字符是.,由于对应的占位符是%f,因此会读取到.45e12(#不是浮点数有效字符,不满足条件),这是采用科学计数法的浮点数格式,转换成小数就是450000000000(没办法在内存里面精确存储)。

二、VS编译器使用scanf函数报错及解决措施

对于VS编译器使用scanf函数会报错的问题以及相应的解决措施,可以翻看我之前写过的一篇文章:解决VS编译器scanf函数报错问题

三、scanf函数返回值

scanf函数的返回值是整数,表示读取到的数据个数。如果没有读取任何项,或者匹配失败,则返回0。如果在成功读取任何数据之前,发⽣了读取错误或者遇到读取到文件结尾,则返回常量EOF(EOF:end of file文件结束的标志,值为-1)。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int a = 0;int b = 0;float f = 0.0f;int r = scanf("%d %d %f", &a, &b, &f);printf("a=%d b=%d f=%f\n", a, b, f);printf("r = %d\n", r);return 0;
}

运行结果:
在这里插入图片描述
上述代码中,r值是2,表示正确读取了2个数值。

四、占位符

scanf占位符与printf基本一致,但在scanf函数使用%c时,不会忽略空白字符,要强制跳过字符前的空⽩字符,可以写成scanf(" %c",&ch),即%c前加上⼀个空格,表表示跳过零个或多个空白字符。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{char ch = '0';scanf("%c", &ch);printf("%c", ch);printf("xxxx");return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

%s占位符:从第一个非空白字符起,一直读到下一个空白字符为止。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{char arr[20] = { 0 };scanf("%s", arr);printf("%s", arr);return 0;
}

运行结果:
在这里插入图片描述
从上述代码可以看出,%s不会包含空⽩字符,所以读取读取多个单词,除⾮多个%s ⼀起使用,scanf函数不适合读取可能包含空格的字符串。另外,%s占位符会在字符串变量末尾存储⼀个空字符\0。
scanf函数将字符串读入字符数组时,不会检测字符串是否超过了数组⻓度,所以,储存字符串时, 可能会超过数组的边界(scanf函数不安全的地方)。为防止出现这种情况,使用%s占位符时,指定读⼊字符串的最大长度,即写成%[m]s。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{char arr[5] = { 0 };scanf("%4s", arr);printf("%s", arr);return 0;
}

运行结果:
在这里插入图片描述

五、赋值忽略符

如果我们不按照规定格式输入数值,scanf函数就会解析失败:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int year = 0;int month = 0;int day = 0;scanf("%d-%d-%d", &year, &month, &day);printf("year=%d month=%d day=%d\n", year, month, day);return 0;
}

运行结果:
在这里插入图片描述
在这里插入图片描述
如果以1993 10 5这种格式输入,解析会,为了避免这种情况,只需要把*(赋值忽略符)加在任何占位符的百分号后⾯,该占位符就不会返回值,解析后将被丢弃。
修改后的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>int main()
{int year = 0;int month = 0;int day = 0;scanf("%d%*c%d%*c%d", &year, &month, &day);printf("year=%d month=%d day=%d\n", year, month, day);return 0;
}

运行结果:
在这里插入图片描述
关于printf函数和scanf函数的介绍就到这里,除了他们两个以外,C语言函数还有很多,像是strcpy、sizeof、strcmp…,感兴趣的小伙伴可以翻看我的其他博客。

http://www.dtcms.com/a/307958.html

相关文章:

  • TCP 连接管理 之 三次握手详解
  • 在Trae中使用MoonBit月兔1 创建项目
  • 力扣-102. 二叉树的层序遍历
  • 【BUG】nvm无法安装低版本Node.js:The system cannot find the file specified解决方案
  • 关于npm前端项目编译时栈溢出 Maximum call stack size exceeded的处理方案
  • 去重、top_n()、pull()、格式化
  • LCM中间件入门(1):工作原理核心概念及Ubuntu环境下的C++实践
  • 如何在NPM上发布自己的React组件(包)
  • 基于岗位需求的康养休闲旅游服务实训室建设方案
  • 达梦(DM8)常用管理SQL命令(3)
  • JavaScript内存管理完全指南:从入门到精通(通俗版+硬核版)
  • python后端之DRF框架(下篇)
  • Linux 服务器性能优化:性能监控,系统性能调优,进程优先级,内核升级全解析
  • 常见的中间件漏洞(tomcat,weblogic,jboss,apache)
  • 制造业企业如何保障文件外发图纸数据安全的?
  • dubbo源码之消费端启动的高性能优化方案
  • CTE公用表表达式的可读性与性能优化
  • Java项目:基于SSM框架实现的小区物业管理系统【ssm+B/S架构+源码+数据库+毕业论文+开题报告+任务书+远程部署】
  • 解决Git升级后出现的问题
  • DeepSeek SEO关键词优化提升流量增长
  • Linux Shell 条件判断:`test`、`[`、`[[` 命令深度解析
  • centos yum更换阿里源
  • 处理vscode在Ubuntu18.04上用不到的方法
  • 【大模型理论篇】跨语言AdaCOT
  • 关于PHP学习
  • 飞算科技:以自主创新引领数字科技浪潮,飞算JavaAI赋能产业智能化升级
  • 亚远景-ASPICE与ISO 26262评估标准:异同解析与协同实践
  • Linux基础练习题1
  • 谷歌正在美国测试一项基于机器学习的年龄识别技术
  • 前端技术栈详解