Linux标准IO(四)-格式化I/O输入
C 库函数提供了 3 个格式化输入函数,包括:scanf()、fscanf()、sscanf(),其函数定义如下所示:
#include <stdio.h>
int scanf(const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int sscanf(const char *str, const char *format, ...);
可以看到,这 3 个格式化输入函数也是可变参函数,它们都有一个共同的参数 format,同样也称为格式控制字符串,用于指定输入数据如何进行格式转换,与格式化输出函数中的 format 参数格式相似,但也有所不同。
每个函数除了固定参数之外,还可携带 0 个或多个可变参数。
scanf()函数可将用户输入(标准输入)的数据进行格式化转换;fscanf()函数从 FILE 指针指定文件中读取数据,并将数据进行格式化转换;sscanf()函数从参数 str 所指向的字符串中读取数据,并将数据进行格式化转换。
scanf()函数
相对于 printf 函数,scanf 函数就简单得多。scanf()函数的功能与 printf()函数正好相反,执行格式化输入功能;即 scanf()函数将用户输入(标准输入)的数据进行格式化转换并进行存储,它从格式化控制字符串format 参数的最左端开始,每遇到一个转换说明便将其与下一个输入数据进行“匹配”,如果二者匹配则继续,否则结束对后面输入的处理。而每遇到一个转换说明,便按该转换说明所描述的格式对其后的输入数据进行转换,然后将转换得到的数据存储于与其对应的输入地址中。以此类推,直到对整个输入数据的处理结束为止。
从函数原型可以看出,scanf()函数也是一个“可变参数函数”,除第一个参数 format 之外,scanf()函数还可以有若干个输入地址(指针),这些指针指向对应的缓冲区,用于存储格式化转换后的数据;且对于每一个输入地址,在格式控制字符串 format 参数中都必须有一个转换说明与之一一对应。即从 format 字符串的左端第 1 个转换说明对应第 1 个输入地址,第 2 个格式说明符对应第 2 个输入地址,第 3 个格式说明符对应第 3 个输入地址,以此类推。譬如:
int a, b, c;
scanf("%d %d %d", &a, &b, &c);
当程序中调用 scanf()的时候,终端会被阻塞,等待用户输入数据,此时我们可以通过键盘输入一些字符,譬如数字、字母或者其它字符,输入完成按回车即可!接着来 scanf()函数就会对用户输入的数据进行格式转换处理。
函数调用成功后,将返回成功匹配和分配的输入项的数量;如果较早匹配失败,则该数目可能小于所提供的数目,甚至为零。发生错误则返回负值。
fscanf()函数
fscanf()函数从指定文件中读取数据,作为格式转换的输入数据,文件通过 FILE 指针指定,所以它有两个固定参数,FILE 指针和格式控制字符串 format。譬如从标准输入文件中读取数据进行格式化转换:
int a, b, c;fscanf(stdin, "%d %d %d", &a, &b, &c);
此时它的作用与 scanf()就是相同的,因为标准输入文件的数据就是用户输入的数据,譬如通过键盘输入的数据。
函数调用成功后,将返回成功匹配和分配的输入项的数量;如果较早匹配失败,则该数目可能小于所提供的数目,甚至为零。发生错误则返回负值。
sscanf()函数
sscanf()将从参数 str 所指向的字符串缓冲区中读取数据,作为格式转换的输入数据,所以它也有两个固定参数,字符串 str 和格式控制字符串 format,譬如:
char *str = "5454 hello";
char buf[10];
int a;
sscanf(str, "%d %s", &a, buf);
函数调用成功后,将返回成功匹配和分配的输入项的数量;如果较早匹配失败,则该数目可能小于所提供的数目,甚至为零。发生错误则返回负值。
格式控制字符串 format
本小节的重点依然是这个 format 参数的格式,与格式化输出函数中的 format 参数格式、写法上比较相似,但也有一些区别。format 字符串包含一个或多个转换说明,每一个转换说明都是以百分号"%"或者"%n$"
开头(n 是一个十进制数字),关于"%n$"这种开头的转换说明就不介绍了,实际上用的不多。
以%百分号开头的转换说明一般格式如下:
%[*][width][length]type
%[m][width][length]type
%后面可选择性添加星号或字母 m,如果添加了星号,格式化输入函数会按照转换说明的指示读取输入,但是丢弃输入,意味着不需要对转换后的结果进行存储,所以也就不需要提供相应的指针参数。
如果添加了 m,它只能与%s、%c 以及%[一起使用,调用者无需分配相应的缓冲区来保存格式转换后的数据,原因在于添加了 m,这些格式化输入函数内部会自动分配足够大小的缓冲区,并将缓冲区的地址值通过与该格式转换相对应的指针参数返回出来,该指针参数应该是指向 char *变量的指针。随后,当不再需要此缓冲区时,调用者应调用 free()函数来释放此缓冲区。譬如:
char *buf;scanf("%ms", &buf);......free(buf);
介绍了星号*和字母 m 之后,再来看看转换说明的格式,中括号[ ]表示的部分是可选的,所以可知,与格式化输出函数中的 format 参数一样,只有 type 字段是必须的。
⚫ width:最大字符宽度;
⚫ length:长度修饰符,与格式化输出函数的 format 参数中的 length 字段意义相同。
⚫ type:指定输入数据的类型。
我们先来看看 type 字段。
(一)type(类型)
此 type 字段与格式化输出函数中的 format 参数的 type 字段是同样的意义,用于指定输入数据的类型,
如下所示:
type 类型描述
(二)width 最大字符宽度
是一个十进制表示的整数,用于指定最大字符宽度,当达到此最大值或发现不匹配的字符时(以先发生者为准),字符的读取将停止。大多数 type 类型会丢弃初始的空白字符,并且这些丢弃的字符不会计入最大字符宽度。对于字符串转换来说,scanf()会在字符串末尾自动添加终止符"\0",最大字符宽度中不包括此终止符。
譬如调用 scanf()函数如下:
scanf("%4s", buf); //匹配字符串,字符串长度不超过 4 个字符
用户输入 abcdefg,按回车,那么只能将 adcd 作为一个字符串存储在 buf 数组中。
(三)length 长度修饰符
与格式化输出函数的格式控制字符串 format 中的 length 字段意义相同,用于对 type 字段进行修饰,扩展识别更多不同长度的数据类型。如下所示:
length 长度修饰符
scanf("%hd", var);//匹配 short int 类型数据
scanf("%hhd", var);//匹配 signed char 类型数据
scanf("%ld", var);//匹配 long int 类型数据
scanf("%f", var);//匹配 float 类型数据
scanf("%lf", var);//匹配 double 类型数据
scanf("%Lf", var);//匹配 long double 类型数据
关于格式化输入函数的 format 参数就介绍到到这里了,接下来编写一个简单地示例进行测试。
使用示例
//示例代码 4.8.2 scanf()函数使用示例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {int a;float b;char *str;printf("请输入一个整数:\n");scanf("%d", &a);printf("你输入的整数为: %d\n", a);printf("请输入一个浮点数:\n");scanf("%f", &b);printf("你输入的浮点数为: %f\n", b);printf("请输入一个字符串:\n");scanf("%ms", &str);printf("你输入的字符串为: %s\n", str);free(str); //释放字符串占用的内存空间exit(0);
}
当程序中调用 scanf()之后,终端就会被阻塞、等待用户输入数据,当我们输入完成之后,按回车即可!
第三个 scanf()函数调用中,使用%m,所以我们不需要提供存放字符串的缓冲区,scanf()函数内部会分配缓冲区,并将缓冲区地址存放在 str 这个我们给定的 char 指针变量中。使用完之后记得调用 free()释放内存即可。
编译测试:
测试结果
相关文章:

Linux标准IO(四)-格式化I/O输入
C 库函数提供了 3 个格式化输入函数,包括:scanf()、fscanf()、sscanf(),其函数定义如下所示: #include <stdio.h> int scanf(const char *format, ...); int fscanf(FILE *stream, const char *format, ...); int sscanf(c…...

分布式安装LNMP
目录 搭建LNMP架构 安装mysql 1.上传mysql软件包,关闭防火墙和核心防护 2.安装环境依赖包,桌面安装可能有自带的数据库除 3.配置软件模块 4.编译及安装 5.创建mysql用户 6.修改mysql 配置文件 7.更改mysql安装目录和配置文件的属主属组 8.设置…...
TFTP协议
目录 一、TFTP协议概述 1.1 TFTP协议简介 1.2 TFTP协议特点 二、TFTP协议原理 2.1 TFTP协议工作流程 2.2 TFTP协议数据包格式 三、TFTP协议应用场景 3.1 网络设备配置文件传输 3.2 虚拟机镜像文件传输 3.3 IoT设备固件升级 四、TFTP协议优化方法 4.1 增加超时重传机…...

FPGA随记-二进制转格雷码
反射二进制码(RBC),也称为反射二进制(RB)或格雷码(Gray code),得名于Frank Gray,是二进制数制的一种排列方式,使得连续两个值之间仅有一个比特(二…...
Android常用C++特性之std::unique_lock
声明:本文内容生成自ChatGPT,目的是为方便大家了解学习作为引用到作者的其他文章中。 std::unique_lock 是 C 标准库中的一种灵活的锁管理类,提供了比 std::lock_guard 更多的功能和灵活性。它可以控制对互斥锁(std::mutex&#x…...

网络与信息安全工程师(工信部教育与考试中心)
在当今数字化时代,大量的敏感信息与业务流程在网络上传输和处理,使得网络与信息安全成为保障企业运营、政务管理以及金融交易等关键领域不可忽视的一环。 因此,对网络安全专家的需求日益增长。 例如,金融机构、大型电信运营商以…...

uni-app+vue3开发微信小程序使用本地图片渲染不出来报错[渲染层网络层错误]Failed to load local image resource
我把图片放在assets里面页面通过相对路径引入。结果一直报错。 最后我把图片放在static文件夹下面。然后修改路径指向static就可以了 或者是我们必须先import 这个图片然后在使用 import banner1 from ../../assets/images/banner/banner1.png; <image :src"banner…...

Leetcode 93-复原 IP 地址
有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 ‘.’ 分隔。 例如:“0.1.2.201” 和 “192.168.1.1” 是 有效 IP 地址,但是 “0.011.255.245”、“192.168.…...
unity 中向指定的动画片段添加动画事件,并播放动画,同时获取动画片段的时长。
示例一 using UnityEngine;using System;public static class AnimationUtils{/// <summary>/// 向指定的动画片段添加动画事件,并播放动画,同时获取动画片段的时长。/// </summary>/// <param name"_animator">需要添加动画…...

JavaEE:探索网络世界的魅力——玩转UDP编程
文章目录 UDPUDP的特点UDP协议端格式校验和前置知识校验和具体是如何工作的? UDP UDP的特点 UDP传输的过程类似于寄信. 无连接: 知道对端的IP和端口号就直接进行传输,不需要建立连接.不可靠: 没有确认机制,没有重传机制,如果因为网络故障导致该段无法到达对方,UDP协议也不会…...

生成式人工智能:企业数字化转型的全新引擎,深度解析The Open Group 2024生态系统架构·可持续发展年度大会
生成式人工智能:企业数字化转型的全新引擎,深度解析The Open Group 2024生态系统架构可持续发展年度大会 随着人工智能技术的飞速发展,生成式人工智能(Generative AI)正以惊人的速度渗透到各行各业,成为企…...
阿里云k8s如何创建可用的api token
阿里云的 Kubernetes 配置文件(如您所提供的 YAML 格式文件)通常不会直接包含用于连接 Kubernetes 集群的令牌。而是包含了客户端证书和私钥数据,这些是用于通过证书验证而不是令牌验证的方式来与 Kubernetes API 服务器进行安全交互的。 1.…...
leetcode刷题day30|贪心算法Part04重叠区间问题(452. 用最少数量的箭引爆气球、435. 无重叠区间、763.划分字母区间)
前言:今天的三道题目都是重叠区间的问题。 452. 用最少数量的箭引爆气球 思路:局部最优:当气球出现重叠,一起射,所用弓箭最少; 全局最优:把所有气球射爆所用弓箭最少。 按照起始位置排序&…...

MQTT客户端实战:从连接到通信。详细说明MQTT客户端和MQTT代理进行通信
EMQX安装 EMQX服务器安装 安装文档,见链接不另外写 https://docs.emqx.com/zh/emqx/latest/deploy/install-ubuntu.html 启动 EMQX 启动为一个 systemd 服务: sudo systemctl start emqx在windows安装客户端 在线 MQTT WebSocket 客户端工具&…...
【go/方法记录】cgo静态库编译以及使用dlv定位cgo崩溃问题
目录 说在前面文件树静态库编译cgo使用崩溃模拟使用dlv定位崩溃参考 说在前面 测试环境:WSL2go版本:go version go1.23.1 linux/amd64gcc版本:gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0cmake版本:3.22.1 文件树 ├── buffer …...

(笔记自用)位运算总结+LeetCode例题:颠倒二进制位+位1的个数
一.位运算总结: 在解题之前理解一下为什么需要位运算?它的本质是什么? 力扣上不少位运算相关的题,并且很多题也会用到位运算的技巧。这又是为什么? 位运算的由来 在计算机里面,任何数据最终都是用数字来表示的&…...

024.PL-SQL进阶—游标
课 程 推 荐我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈虚 拟 环 境 搭 建 :…...

从零开始使用树莓派debian系统使用opencv4.10.0进行人脸识别(保姆级教程)
一、总体架构 本文主要是使用树莓派自带的csi摄像头,搭配上opencv4.10.0进行物体的识别。本文使用的环境是python3.7.3,环境不一样有可能安装的opencv的过程也会很不一样,但是python的环境我们可以自己自行安装。 二、树莓派系统的安装 本文…...

golang qq邮件发送验证码
验证码的使用场景 注册/登录:使用验证码可以有效减少垃圾账号注册和恶意登录;短信接口保护:高效减少防止短信接口被刷情况;提交/投票:有效减少恶意刷单、恶意提交、恶意投票等情况;密码找回:用…...

鸿蒙 OS 开发单词打卡 APP 项目实战 20240922 笔记和源码分享
配套有完整的录播课, 需要的私信. 零基础入门级别, 有点前端基础都能学会. 效果截图: 代码截图: 页面完整代码: import { AnswerStatus } from ../enums/AnswerStatus import { PracticeStatus } from ../enums/PracticeStatus import { getRandomQuestions, Question …...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

srs linux
下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935,SRS管理页面端口是8080,可…...

Python爬虫(一):爬虫伪装
一、网站防爬机制概述 在当今互联网环境中,具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类: 身份验证机制:直接将未经授权的爬虫阻挡在外反爬技术体系:通过各种技术手段增加爬虫获取数据的难度…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”
目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

C++使用 new 来创建动态数组
问题: 不能使用变量定义数组大小 原因: 这是因为数组在内存中是连续存储的,编译器需要在编译阶段就确定数组的大小,以便正确地分配内存空间。如果允许使用变量来定义数组的大小,那么编译器就无法在编译时确定数组的大…...
MySQL 索引底层结构揭秘:B-Tree 与 B+Tree 的区别与应用
文章目录 一、背景知识:什么是 B-Tree 和 BTree? B-Tree(平衡多路查找树) BTree(B-Tree 的变种) 二、结构对比:一张图看懂 三、为什么 MySQL InnoDB 选择 BTree? 1. 范围查询更快 2…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...
【前端异常】JavaScript错误处理:分析 Uncaught (in promise) error
在前端开发中,JavaScript 异常是不可避免的。随着现代前端应用越来越多地使用异步操作(如 Promise、async/await 等),开发者常常会遇到 Uncaught (in promise) error 错误。这个错误是由于未正确处理 Promise 的拒绝(r…...