【C++】深度剖析 scanf 函数:原理、应用与优化

news2024/12/25 9:02:06

在这里插入图片描述

博客主页: [小ᶻ☡꙳ᵃⁱᵍᶜ꙳]
本文专栏: C++

文章目录

  • 💯前言
  • 💯`scanf` 函数的基本原理
  • 💯基本用法示例
    • 常见占位符
      • 示例
  • 💯使用 `scanf` 时的注意事项
  • 💯引入 `cstdio` 头文件
  • 💯`scanf` 与 `cin` 的对比
  • 💯`scanf` 的返回值
  • 💯输入格式一致性的重要性
    • 示例 1:使用空格分隔输入
    • 示例 2:使用逗号分隔输入
    • 示例 3:取地址符的重要性
  • 💯小结


在这里插入图片描述


💯前言

  • C++ 中,scanf 函数源于 C 语言标准库,旨在从标准输入设备中接收用户数据。尽管 C++ 提供了更现代化的输入方式,如 cin,但在某些特定场景下,scanf 依然具备显著的优势,尤其是在大规模数据处理和对输入延迟要求较高的程序中,其效率和简洁性成为重要考量。本文将深入探讨 scanfC++ 中的具体用法、它与其他输入方法的对比,并分析其在特定情境下的独特适用性
    C++ 参考手册
    在这里插入图片描述

💯scanf 函数的基本原理

scanf 函数的主要功能是从标准输入(通常是键盘)中读取数据。运行到 scanf 的代码行时,程序会暂停执行,直到用户提供输入并按下回车键。这种阻塞机制使得 scanf 在等待用户提供必要信息的场景中特别有效。具体来说,scanf 是通过解析输入流并将数据写入提供的地址中来工作的。

scanf 的函数原型如下:

int scanf(const char *format, ...);
  • format:格式字符串,用于定义待输入的数据类型和顺序,如整数、浮点数、字符等。开发者通过这种格式字符串来精确控制 scanf 的输入解析方式。
  • ...:可变参数,用于接收输入数据的地址。这种设计使得 scanf 能够动态地将输入值存储到相应的变量中。

scanf 的返回值是成功读取的数据项的数量,这对于判断输入是否成功至关重要。例如,当输入格式不匹配时,scanf 会返回一个小于预期的值,开发者据此可以实施错误处理逻辑,以提高程序的健壮性。

在这里插入图片描述


💯基本用法示例

scanf 的用法类似于 printf,它们都使用格式说明符来处理数据类型。例如:

int num;
scanf("%d", &num); // 读取一个整数,并存入变量 num 中

在这个示例中,%d 是格式说明符,表示期望读取一个整数。&num 代表变量 num 的地址,scanf 需要这个地址来将用户输入的数据存储进去。如果省略地址符号 &,则 scanf 无法定位变量的内存位置,导致编译错误。
在这里插入图片描述


常见占位符

scanf() 中使用的格式说明符与 printf() 基本一致,以下是一些常用占位符:

占位符介绍
%c读取单个字符(包括空格和换行符)。
%d读取整数(int 类型)。
%f读取 float 类型浮点数。
%lf读取 double 类型浮点数。
%Lf读取 long double 类型浮点数。
%s读取字符串(不包括空格和换行符,遇到空格会停止)。
%[]在方括号中指定一组匹配的字符(如 %[0-9]),遇到不在集合之中的字符时,匹配终止。

特别需要注意的是,所有占位符(除 %c 之外)在处理输入时会自动忽略起始的空白字符。而 %c 则直接读取当前的字符,包括空格或换行符。如果希望 %c 自动跳过空白字符,可以在其前面加上空格,如:scanf(" %c", &ch)

  1. %c前面不加空格
    #include <cstdio>
    
    int main()
    {
    	char a;
    	scanf("%c", &a);
    	printf("----%c----", a);
    	return 0;
    } 
    
    在这里插入图片描述
  2. %c前面加空格
    #include <cstdio>
    
    int main()
    {
    	char a;
    	scanf(" %c", &a);
    	printf("----%c----", a);
    	return 0;
    } 
    
    在这里插入图片描述

示例

在这里插入图片描述

float f;
char ch;
char str[50];

scanf("%f %c %s", &f, &ch, str); // 读取一个浮点数、一个字符和一个字符串

在上述代码中,用户依次输入一个浮点数、一个字符和一个字符串,scanf 会将这些数据分别存储到相应的变量中。需要注意的是 %s 在读取字符串时,遇到空格或换行符会停止,这意味着多词的字符串需要其他方法来读取,例如 fgetsgetline

小提示:

  1. scanf 的占位符后一般不使用 \n,因为 \n 是输出时的换行符,在输入时没有实际作用。
  2. scanf() 处理数值占位符时,会自动过滤空白字符,包括空格、制表符和换行符。因此,用户输入的数据之间有一个或多个空格并不影响 scanf() 读取数据,输入被分为几行也不会影响数据读取。

💯使用 scanf 时的注意事项

在这里插入图片描述

  1. 地址符号(&):对于 scanf,需要传递变量的地址,以便函数能够修改变量的值。地址符号 & 告诉 scanf 应将输入值存储到哪个内存位置。因此,省略 & 会导致程序无法编译。

  2. 输入的格式和顺序:用户的输入必须严格遵循格式说明符的要求。如果期望读取整数但用户输入了字符,scanf 会因无法匹配而导致输入失败。因此,开发者必须做好输入验证,特别是在可靠性要求较高的程序中。

  3. 字符串输入%s 读取字符串时会在遇到空格或换行符时停止。因此,scanf 不适用于读取包含空格的长字符串,这种情况下建议使用其他函数如 getline()fgets()

  4. 输入缓冲区:当读取字符时,输入缓冲区可能会带来问题。例如,如果之前的输入留下了换行符或空格,这些字符可能会被 %c 捕获。为避免这种情况,可以在 scanf(" %c", &ch) 前加一个空格,这样可以跳过空白字符。


💯引入 cstdio 头文件

为了在 C++ 中使用 scanf 函数,需要引入 cstdio 头文件,它包含了 C 标准库中的输入/输出函数,如 scanfprintf

#include <cstdio>

在这里插入图片描述

通过引入 cstdio,C++ 程序员可以继续使用这些高效的 C 语言输入/输出函数。尤其在某些特定场景中,例如竞赛编程或对性能要求极高的系统中,scanf 的高效率使其非常有用。


💯scanfcin 的对比

在 C++ 中,cin 是一种更现代、更安全的输入方式,因为它提供了类型安全性和易于操作的流功能。然而,scanf 在输入效率上通常优于 cin,尤其是在处理大量输入时。特别是在竞赛编程中,scanf 的简洁和高效使其在很多时候成为首选。

例如:

int num;
std::cin >> num; // 读取一个整数,并存入变量 num 中

scanf 相比,cin 更具可读性且更符合现代 C++ 的风格,但由于 cin 的复杂性,其在处理输入时的速度可能会比 scanf 慢。在需要处理大量数据输入的场合,scanf 的优势尤为明显。
在这里插入图片描述


💯scanf 的返回值

scanf() 的返回值是一个整数,表示成功读取的变量个数。如果没有读取任何项,或者输入不符合预期,scanf 会返回 0,表示没有成功匹配输入。如果发生读取错误或遇到文件结尾,scanf 则返回 EOF(通常为 -1)。通过检查返回值,程序可以判断输入的有效性,从而实现必要的错误处理。

例如:

int x;
if (scanf("%d", &x) != 1) {
    printf("输入错误,请输入一个整数\n");
}

这种检查方式使得程序更为健壮,能够在输入错误时提供相应的提示或处理,避免因无效输入导致程序崩溃。

#include <cstdio>

#include <cstdio>

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 c = %f\n", a, b, f);
	printf("r = %d\n", r);
	return 0;
}
  1. 正常接收
    在这里插入图片描述
  2. 第三位出现匹配失败字符
    在这里插入图片描述
  3. 前面匹配失败,后面也无法正常匹配。
    在这里插入图片描述

💯输入格式一致性的重要性

输入格式必须严格符合 scanf 定义的格式,否则会导致输入失败或错误结果。下面的两个示例展示了不同输入格式的行为:
在这里插入图片描述


示例 1:使用空格分隔输入

#include <cstdio>

int main()
{
    int a, b, c, d;
    scanf("%d %d %d %d", &a, &b, &c, &d);
    printf("%d %d %d %d", a, b, c, d);
    return 0;
}

在这里插入图片描述

在这个示例中,用户需要输入四个整数,并使用空格分隔。例如输入:1 2 3 4。程序会正确读取并输出这四个整数。


示例 2:使用逗号分隔输入

#include <cstdio>

int main()
{
    int a, b, c, d;
    scanf("%d,%d,%d,%d", &a, &b, &c, &d);
    printf("%d %d %d %d", a, b, c, d);
    return 0;
}

在这里插入图片描述

在这个示例中,用户需要输入四个整数,并使用逗号分隔,例如:1,2,3,4。如果用户未按照逗号格式进行输入,scanf 将无法正确读取所有数据,导致程序的输出结果不符合预期。


示例 3:取地址符的重要性

#include <cstdio>

int main()
{
    int a;
    scanf("%d", &a);
    printf("%d", a);
    return 0;
}

在这里插入图片描述

在这个示例中,a 的地址通过 &a 传递给 scanf。如果省略 &,编译器将无法通过,因为 scanf 需要知道变量的内存地址才能正确存储用户输入的值。输入一个整数后,程序会将其打印出来,例如输入:1,程序输出:1


💯小结

  • 在这里插入图片描述
    scanf 函数是 C/C++ 中用于接收用户输入的重要工具。它的高效性灵活性使得它在许多场景中依然被广泛应用。特别是在交互式程序中,scanf 提供了一种快速而直接的用户输入方式。熟练掌握 scanf 的用法,包括格式说明符的使用地址传递的机制、以及正确的错误处理方法,对于编写健壮的 C/C++ 程序非常关键。
    在学习 scanf 的过程中,鼓励多进行实践,尝试不同的数据类型和输入场景,理解 scanf 的各种细节。随着不断的练习和积累,你会发现在复杂的开发环境中scanf 的灵活运用能够为程序带来极大的便利和效率提升。掌握这些技术,将极大增强你对 CC++ 输入输出机制的理解,使你能够编写出更高效且健壮的代码。不论是在基础编程学习中,还是在大型项目开发中,scanf 都是一个强有力的工具,为你的程序设计提供更多的可能性灵活性

在这里插入图片描述


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2252320.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YOLOv1 (You Only Look Once)

YOLO (You Only Look Once) 是一种经典的目标检测算法&#xff0c;旨在通过一个统一的卷积神经网络&#xff08;CNN&#xff09;进行目标检测&#xff0c;最大化检测速度并保持较高的精度。YOLO 在目标检测领域产生了巨大的影响&#xff0c;并且经过了多个版本的迭代。下面是 Y…

【Verilog】实验二 数据选择器的设计与vivado集成开发环境

目录 一、实验目的 二、实验环境 三、实验任务 四、实验原理 五、实验步骤 top.v mux2_1.v 一、实验目的 1. 掌握数据选择器的工作原理和逻辑功能。 2. 熟悉vivado集成开发环境。 3. 熟悉vivado中进行开发设计的流程。 二、实验环境 1. 装有vivado的计算机。 2. Sw…

【CSS in Depth 2 精译_063】10.2 深入理解 CSS 容器查询中的容器

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第十章 CSS 容器查询】 ✔️ 10.1 容器查询的一个简单示例 10.1.1 容器尺寸查询的用法 10.2 深入理解容器 ✔️ 10.2.1 容器的类型 ✔️10.2.2 容器的名称 ✔️10.2.3 容器与模块化 CSS ✔️ 10.3…

今天我们来聊聊Maven中两个高级的概念—— 插件和目标

插件&#xff08;plugin&#xff09; Maven的核心是一个插件执行框架;所有的工作都是由插件完成的。 Maven中Plugin分为两种类型&#xff1a; build类型Plugin只能在build阶段执行&#xff0c;在POM中需要在 <build/> 标签下进行配置。 reporting类型&#xff1a;在si…

【触想智能】自动售票机选择工控一体机配套的原因分析

自动售票机是现代公共交通系统中常见的设备之一&#xff0c;它能够方便、快速地为乘客提供票务服务。为了实现高效、可靠的运营&#xff0c;许多自动售票机都采用工控一体机作为核心控制硬件。 触想工控一体机TPC-W200系列 下面&#xff0c;触想智能小编为大家分析为什么自动售…

[计算机网络] HTTP/HTTPS

一. HTTP/HTTPS简介 1.1 HTTP HTTP&#xff08;超文本传输协议&#xff0c;Hypertext Transfer Protocol&#xff09;是一种用于从网络传输超文本到本地浏览器的传输协议。它定义了客户端与服务器之间请求和响应的格式。HTTP 工作在 TCP/IP 模型之上&#xff0c;通常使用端口 …

element-ui的下拉框报错:Cannot read properties of null (reading ‘disabled‘)

在使用element下拉框时&#xff0c;下拉框option必须点击输入框才关闭&#xff0c;点击其他地方报错&#xff1a;Cannot read properties of null (reading disabled) 造成报错原因&#xff1a;项目中使用了el-dropdown组件&#xff0c;但是在el-dropdown里面没有定义el-dropdo…

新一代零样本无训练目标检测

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月2日21点02分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文链接 点击开启你的论文编程之旅h…

30.100ASK_T113-PRO 用QT编写视频播放器(一)

1.再buildroot中添加视频解码库 X264, 执行 make menuconfig Target packages -->Libraries --> Multimedia --> X264 CLI 还需要添加 FFmpeg 2. 保存,重新编译 make all 3.将镜像下载开发板

Python办公自动化,批量生成Excel案例数据集

在数据分析的世界里&#xff0c;数据是核心&#xff0c;而如何高效地生成和处理数据则成为每位数据分析师必备的技能之一。今天&#xff0c;我们要探讨一个有趣的话题——“造数”。 但这里的“造数”并非意味着编造数据&#xff0c;而是指在确保数据安全的前提下&#xff0c;…

在线绘制Nature Communication同款双色、四色火山图,突出感兴趣的基因

导读&#xff1a;火山图通常使用三种颜色分别表示显著上调&#xff0c;显著下调和不显著。通过为特定的数据点添加另一种颜色&#xff0c;可以创建双色或四色火山图&#xff0c;从而更直观地突出感兴趣的数据点。 《Nature Communication》文章“Molecular and functional land…

【大语言模型】ACL2024论文-23 检索增强的多语言知识编辑

【大语言模型】ACL2024论文-23 检索增强的多语言知识编辑 目录 文章目录 【大语言模型】ACL2024论文-23 检索增强的多语言知识编辑目录摘要研究背景问题与挑战如何解决核心创新点算法模型实验效果&#xff08;包含重要数据与结论&#xff09;相关工作后续优化方向 后记 检索增强…

ETSI EN 300328 标准的一些笔记

ETSI - European Telecommunications Standards Institute 欧洲电信标准化协会 ETSI EN 300328 是欧洲协调标准&#xff0c;此标准适用于工作在2.4G频段范围内运行的宽频传输系统和设备的无线电频谱。 例如 WIFI、Zigbee、蓝牙、 (国内的星闪)。不涵盖UWB。 符合了EN 300328标…

VSCode:代码格式化插件

settings.json文件中添加如下配置并保存 {"workbench.sideBar.location": "left","cssrem.rootFontSize": 80,"git.ignoreWindowsGit27Warning": true,"eslint.codeAction.showDocumentation": {"enable": true…

Redis实现限量优惠券的秒杀

核心&#xff1a;避免超卖问题&#xff0c;保证一人一单 业务逻辑 代码步骤分析 全部代码 Service public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {Resourceprivate ISeckillVoucher…

Github提交Pull Request教程 Git基础扫盲(零基础易懂)

1 PR是什么&#xff1f; PR&#xff0c;全称Pull Request&#xff08;拉取请求&#xff09;&#xff0c;是一种非常重要的协作机制&#xff0c;它是 Git 和 GitHub 等代码托管平台中常见的功能&#xff0c;被广泛用于参与社区贡献&#xff0c;从而促进项目的发展。 PR的整个过…

大数据技术Kafka详解 ② | Kafka基础与架构介绍

目录 1、kafka的基本介绍 2、kafka的好处 3、分布式发布与订阅系统 4、kafka的主要应用场景 4.1、指标分析 4.2、日志聚合解决方法 4.3、流式处理 5、kafka架构 6、kafka主要组件 6.1、producer(生产者) 6.2、topic(主题) 6.3、partition(分区) 6.4、consumer(消费…

Docker中配置Mysql主从备份

Mysql配置主从备份 一、Docker中实现跨服务器主从备份二、配置步骤1.配置主库2.配置从库3.遇到问题3.其它使用到的命令 一、Docker中实现跨服务器主从备份 在 Docker 中配置 MySQL 主从备份主要通过 MySQL 主从复制实现 二、配置步骤 1.配置主库 # 进入mysql主库容器 docke…

组态王实现设备OEE数据采集的项目总结

组态王实现设备OEE数据采集的项目总结 方案设计硬件设计软件设计 难点总结数据通讯数据转换报表数据存储 项目拓展 最近在做一个项目&#xff0c;关于采集设备OEE数据。陆陆续续做了小半个月&#xff0c;现在算告一段落&#xff0c;特整理总结。 方案设计 硬件设计 本项目是…

C++《set与map》

在之前我们已经学习了解了CSTL当中的string和vector等容器&#xff0c;现在我们已经懂得了这些容器提供的接口该如何使用&#xff0c;并且了解了这些容器的底层结构。接下来我们在本篇当中将继续学习STL内的容器set与map&#xff0c;在此这两个容器与我们之前学习的容器提供的成…