嵌入式Linux系统编程 — 2.3 标准I/O库:格式化I/O

目录

1 格式化I/O简介

2 格式化输出

2.1 格式化输出函数简介

2.2 格式控制字符串 format

2.3 示例程序

3 格式化输入

3.1 格式化输入简介

3.2 格式控制字符串 format

3.3 示例程序


1 格式化I/O简介

在先前示例代码中,经常使用库函数 printf() 来输出程序中的打印信息,printf() 函数能够将格式化的数据输出到标准输出设备,因此它通常被称为格式化输出函数。除了 printf(),还提供了其他几种格式化输出函数,包括 fprintf()dprintf()sprintf()snprintf()

与格式化输出相对应的是格式化输入,它允许从标准输入中获取格式化数据。格式化输入函数包括 scanf()fscanf()sscanf()

2 格式化输出

2.1 格式化输出函数简介

C 库函数提供了 5 个格式化输出函数,包括: printf()、 fprintf()、 dprintf()、 sprintf()、 snprintf(),其函数定义如下所示:

printf():将格式化的数据输出到标准输出(通常是终端或控制台)。

int printf(const char *format, ...);

fprintf():将格式化的数据输出到指定的文件,stream 参数可以是任何有效的文件指针。

int fprintf(FILE *stream, const char *format, ...);

dprintf():直接将格式化的数据写入到指定的文件描述符 fd

int dprintf(int fd, const char *format, ...);

sprintf():将格式化的数据写入到字符数组 str 中,这通常用于字符串操作。

int sprintf(char *str, const char *format, ...);

snprintf():类似于 sprintf(),但增加了对输出缓冲区大小的限制,size 参数指定了最大可写入的字符数,包括结尾的空字符。

int snprintf(char *str, size_t size, const char *format, ...);

2.2 格式控制字符串 format

格式化输出函数中的format 参数称为格式控制字符串,顾名思义,首先它是一个字符串的形式,其次它能够控制后续变参的格式转换。格式控制字符串由两部分组成:普通字符(非%字符) 和转换说明。普通字符会进行原样输出,每个转换说明都会对应后续的一个参数,通常有几个转换说明就需要提供几个参数, 使之一一对应。如下所示:

printf("转换说明 1 转换说明 2 转换说明 3", arg1, arg2, arg3);

格式控制字符串(format )定义了输出数据的格式,包括数据类型、宽度、精度、填充字符等。格式控制字符串通常包括以下几个部分:

转换说明符(Conversion Specifier):指定要输出的数据类型,例如:

  • %d 表示十进制整数。
  • %f 表示浮点数。
  • %s 表示字符串。
  • %c 表示字符。
  • %x 或 %X 表示十六进制整数(小写或大写)。

标志(Flags):可以改变输出格式的选项,例如:

  • %- 表示左对齐。
  • %+ 表示总是显示正负号。
  • %0 表示使用零填充到指定宽度。
  • %# 表示显示八进制数的前缀 0 或十六进制数的前缀 0x 或 0X

宽度(Width):指定输出的最小字符数,如果数据不足,会用空格或指定的填充字符填充。

精度(Precision):对于浮点数,指定小数点后的位数;对于字符串,指定最大字符数。

长度修饰符(Length Modifier):指定数据的长度,例如:

  • %l 表示长整型(long int)。
  • %h 表示短整型(short int)。
  • %ll 表示长长整型(long long int)。

填充字符:如果指定了宽度,可以使用填充字符来填充输出,例如 %10s 会输出一个字符串,并且在其前后填充空格直到宽度达到10个字符。

每个转换说明都是以%字符开头,只有%和 type 字段是必须的,其余都是可选的。其格式如下所示(使用[ ]括起来的部分是可选的) :

%[flags][width][.precision][length]type

例如下面的示例输出:

printf("%d\n", 123);
//输出:123
//注释:以十进制形式输出整数123,后面跟着一个换行符。

printf("%o\n", 123);
//输出:173
//注释:将整数123转换为八进制形式并输出,后面跟着一个换行符。在八进制中,123等于173。

printf("%06d", 1000);
//输出:001000
//注释:以零填充到至少6位的宽度输出整数1000。由于1000不足6位,前面用0填充。

printf("%.8f\n", 520.1314);
//输出:520.13140000
//注释:以浮点数形式输出520.1314,精度指定为8位小数,因此输出时会显示8位小数,即使最后几位是0。

printf("%lld\n", 12345);
//输出:12345
//注释:将整数12345以long long int类型输出,lld是长度修饰符,表示长长整型(64位)。即使没有这个修饰符,大多数现代编译器也会将整型默认为int类型,但使用lld可以确保在所有编译器中都以长整型处理。

2.3 示例程序

下面的程序展示了 printf()fprintf()dprintf()sprintf()snprintf() 函数的使用。每个函数都用来输出格式化的字符串,但它们输出到的地方不同。

#include <stdio.h>

int main() {
    int number = 10;
    char str[] = "Hello, World!";
    float pi = 3.14159;

    // 使用 printf() 输出到标准输出
    printf("Standard output: %s\n", str);

    // 使用 fprintf() 输出到文件
    FILE *file = fopen("output.txt", "w");
    if (file != NULL) {
        fprintf(file, "File output: %s\n", str);
        fclose(file);
    }

    // 使用 dprintf() 输出到文件描述符
    dprintf(fileno(stdout), "Standard output descriptor: %d\n", number);

    // 使用 sprintf() 将格式化字符串存储到字符数组
    char buffer[100];
    sprintf(buffer, "Buffer output: %.2f\n", pi);
    printf("%s", buffer);

    // 使用 snprintf() 将格式化字符串存储到字符数组,限制长度
    snprintf(buffer, sizeof(buffer), "Buffer output with limit: %.2f\n", pi);
    printf("%s", buffer);

    return 0;
}
  • printf() 直接将格式化的字符串输出到标准输出(通常是控制台)。
  • fprintf() 需要一个文件指针作为第一个参数,然后将格式化的字符串写入到该文件。
  • dprintf() 类似于 fprintf(),但它使用文件描述符而不是文件指针。
  • sprintf() 将格式化的字符串存储到提供的字符数组中。需要确保数组足够大以避免溢出。
  • snprintf() 与 sprintf() 类似,但提供了一个额外的长度参数来限制写入的字符数,这有助于防止溢出。

程序运行的结果如下:

3 格式化输入

3.1 格式化输入简介

C 库函数提供了 3 个格式化输入函数,包括: scanf()、 fscanf()、 sscanf(),下面是每个函数的简要介绍:

scanf():从标准输入(通常是键盘输入)读取格式化输入。

int scanf(const char *format, ...);

fscanf():从指定的文件中读取格式化输入,文件通过 FILE 指针指定,它有两个固定参数, FILE 指针和格式控制字符串 format。

int fscanf(FILE *stream, const char *format, ...);

 sscanf():从字符串中读取格式化输入。

int sscanf(const char *str, const char *format, ...);

3.2 格式控制字符串 format

与格式化输出函数中的 format 参数格式、写法上比较相似,但也有一些区别。 format 字符串包含一个或多个转换说明,每一个转换说明都是以百分号"%"或者"%n$"开头(n 是一个十进制数字),关于"%n$"这种开头的转换说明使用的不多。

转换格式与输入类似,以%百分号开头的转换说明一般格式如下:

%[*][width][length]type
%[m][width][length]type

%*不会对转换后的结果进行存储:后面可选择性添加星号*或字母 m,如果添加了星号*,格式化输入函数会按照转换说明的指示读取输入,但是丢弃输入,意味着不需要对转换后的结果进行存储,所以也就不需要提供相应的指针参数。
%m会对转换后的结果进行存储:如果添加了 m,它只能与%s、 %c 以及%[一起使用,调用者无需分配相应的缓冲区来保存格式转换后的数据,原因在于添加了 m,这些格式化输入函数内部会自动分配足够大小的缓冲区,并将缓冲区的地址值通过与该格式转换相对应的指针参数返回出来,该指针参数应该是指向 char *变量的指针。随后,当不再需要此缓冲区时,调用者应调用 free()函数来释放此缓冲区。

3.3 示例程序

下面的程序演示了标准输入输出函数 scanf()fprintf()fscanf()sscanf() 的基本用法。

#include <stdio.h>

int main() {
    int i;
    float f;
    char s[50];
    FILE *file;

    // 使用 scanf() 从标准输入读取整数和浮点数
    printf("Enter an integer and a float: ");
    scanf("%d %f", &i, &f);
    printf("You entered: %d, %.2f\n", i, f);

    // 写入数据到 input.txt 文件
    file = fopen("input.txt", "w");
    if (file == NULL) {
        printf("Failed to open file for writing.\n");
    } else {
        fprintf(file, "fscanf test!\n");
        fclose(file);
    }

    // 读取 input.txt 文件中的数据
    file = fopen("input.txt", "r");
    if (file == NULL) {
        printf("Failed to open file for reading.\n");
    } else {
        fscanf(file, "%8s ", s);
        printf("Read from file: %s\n", s);
        fclose(file);
    }

    // 使用 sscanf() 从字符串读取数据
    sscanf("123 456.78 Hello", "%d %f %s", &i, &f, s);
    printf("Parsed: %d, %.2f, %s\n", i, f, s);

    return 0;
}

代码首先通过 scanf() 从用户那里获取一个整数和一个浮点数,并打印出来。然后写入文本到 input.txt 文件,并通过fscanf()读取这个文件的前8个字符,打印读取的内容。最后通过 sscanf() 从固定字符串中解析数据,并将结果输出。程序运行结果如下:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据分析中的统计学基础及Python具体实现【数据分析】

各位大佬好 &#xff0c;这里是阿川的博客&#xff0c;祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 Python 初阶 Python–语言基础与由来介绍 Python–…

python的line[:-1]和line[-1]

line[:-1]其实就是去除了这行文本的最后一个字符(换行符)后剩下的部分。 line = "abcde" line[:-1] 结果为:abcd line = "abcde" line[::-1] 结果为:edcba 示例3 [m : ] 代表列表中的第m+1项到最后一项 [ : n] 代表列表中的第一项到第n项 [-1] 代…

基于jeecgboot-vue3的Flowable流程-已办任务(一)

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、api接口部分 import { defHttp } from //utils/http/axios;enum Api {flowRecord /flowable/task/flowRecord,finishedListNew /flowable/task/finishedListNew,revokeProcess /flo…

2024年自然语言处理科学与信息检索技术国际会议(ICNLPSIRT 2024)

2024年自然语言处理科学与信息检索技术国际会议(ICNLPSIRT 2024) 2024 International Conference on Natural Language Processing Science and Information Retrieval Technology (ICNLPSIRT 2024) 会议地点&#xff1a;武汉&#xff0c;中国 网址&#xff1a;http://www.i…

【递归、搜索与回溯】搜索

搜索 1.计算布尔二叉树的值2.求根节点到叶节点数字之和3. 二叉树剪枝4.验证二叉搜索树5.二叉搜索树中第K小的元素6.二叉树的所有路径 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&#xff0c;我们一…

深入ES6:解锁 JavaScript 类与继承的高级玩法

个人主页&#xff1a;学习前端的小z 个人专栏&#xff1a;JavaScript 精粹 本专栏旨在分享记录每日学习的前端知识和学习笔记的归纳总结&#xff0c;欢迎大家在评论区交流讨论&#xff01; ES5、ES6介绍 文章目录 &#x1f4af;Class&#x1f35f;1 类的由来&#x1f35f;2 co…

【文献阅读】LORA: LOW-RANK ADAPTATION OF LARGE LANGUAGE MODELS

目录 1. motivation2. overall3. model3.1 low rank parametrized update matrices3.2 applying lora to transformer 4. limitation5. experiment6. 代码参考文献 1. motivation 常规的adaptation需要的微调成本过大现有方法的不足&#xff1a; Adapter Layers Introduce Inf…

视创云展元宇宙虚拟展厅:开启无限可能的沉浸式体验

随着科技的飞速发展&#xff0c;元宇宙虚拟展厅已逐步成为展览行业的新宠。视创云展元宇宙虚拟展厅以其独特的魅力&#xff0c;将参观者从传统展览场所的束缚中解放出来&#xff0c;为他们呈现了一个更为广阔、更为丰富的虚拟世界。通过数字虚拟展厅这一载体&#xff0c;参观者…

如何掌握 Java 正则表达式 的基本语法及在 Java 中的应用

正则表达式是一种用于匹配字符串的模式&#xff0c;在许多编程语言中广泛使用。Java 正则表达式提供了强大的文本处理能力&#xff0c;能够对字符串进行查找、替换、分割等操作。 一、正则表达式的基本语法 正则表达式由普通字符和特殊字符组成。普通字符包括字母、数字和标点…

【Android】主界面设置-封装

在bulid文件写网址 implementation("io.github.youth5201314:banner:2.2.1") 添加主界面图片 些内容 在界面有图片&#xff0c;相同的属性封装起来 在values新建 先写风格&#xff0c;&#xff0c;再写代码 先写好这几项&#xff0c;宽高比例位置 将相同的属性…

软硬件集成项目,这个项目管理软件做的成本预算管理深得我心

最近&#xff0c;我负责了一个中大型的软硬件集成的项目&#xff0c;是对某单位的车间进行智能化改造&#xff0c;以提高生产效率&#xff0c;要确保设备运行的稳定性和安全性。项目会涉及到大量的硬件采购、安装以及多个软件的开发、集成&#xff0c;所以在实施过程中遇到了多…

【Python】实现极致:克服PyInstaller打包挑战,解决libpython3.10.so.1.0库丢失难题

【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题 大家好 我是寸铁&#x1f44a; 总结了一篇【Python】实现极致&#xff1a;克服PyInstaller打包挑战&#xff0c;解决libpython3.10.so.1.0库丢失难题✨ 喜欢的小伙伴可以…

微软必应地图的三维实景功能

偶然看到微软必应地图的三维实景功能&#xff0c;由于比较感兴趣这方面的技术&#xff0c;所以试用了一下,感觉总体来说技术上比咱们自己的技术和设计要好很多。比如这个工具栏就设计的很简洁&#xff0c;人性化&#xff1a; 而且实景地图的范围也非常大&#xff0c;建立这么大…

Windows系统中不同Java版本共存

Windows系统中不同Java版本共存的方法 在Windows系统中&#xff0c;有时我们需要同时运行多个Java应用&#xff0c;而这些应用可能依赖于不同版本的Java Development Kit (JDK) 或 Java Runtime Environment (JRE)。为了实现这种需求&#xff0c;我们需要在Windows中配置多个J…

自养号测评防关联的关键点解析, 确保店铺权重和买家账号的安全稳定

现在很多大卖都是自己管理几百个账号&#xff0c;交给服务商不是特别靠谱。你不知道服务商账号质量怎么样&#xff0c;账号一天下了多少你也不清楚&#xff0c;如果下了很多单万一封号被关联了怎么办&#xff0c;你也不知道服务商用什么卡给你下单&#xff0c;用一些低汇率和黑…

【Python Cookbook】S02E04 文本模式的匹配和查找 match()、search()、findall() 以及 捕获组和 + 的含义

目录 问题解决方案讨论 问题 本文讨论一些按照特定的文本模式进行的查找和匹配。 解决方案 如果想要匹配的只是简单文字&#xff0c;通常我们使用一些内置的基本字符串方法即可&#xff0c;如&#xff1a;str.find()&#xff0c;str.startwith()&#xff0c;str.endswith() …

qmt量化交易策略小白学习笔记第17期【qmt编程之获取对应周期的北向南向数据--方式1:内置python】

qmt编程之获取对应周期的北向南向数据 qmt更加详细的教程方法&#xff0c;会持续慢慢梳理。 也可找寻博主的历史文章&#xff0c;搜索关键词查看解决方案 &#xff01; 感谢关注&#xff0c;咨询免费开通量化回测与获取实盘权限&#xff0c;欢迎和博主联系&#xff01; 获取…

Qwen2本地部署的实战教程

大家好,我是herosunly。985院校硕士毕业,现担任算法研究员一职,热衷于机器学习算法研究与应用。曾获得阿里云天池比赛第一名,CCF比赛第二名,科大讯飞比赛第三名。拥有多项发明专利。对机器学习和深度学习拥有自己独到的见解。曾经辅导过若干个非计算机专业的学生进入到算法…

重塑状态管理的艺术:Vue3中Pinia的魔法之旅内包含简易购物车案例

前言 在Vue.js的世界里&#xff0c;每一次更新都是一次进化&#xff0c;Vue3携带着更强大的性能与灵活性翩然而至。而在这场技术盛宴中&#xff0c;Pinia以一种优雅而革命性的方式&#xff0c;重新定义了状态管理的体验。如果说Vuex是Vue2时代的王者&#xff0c;那么Pinia无疑…

024、工具_慢查

1)发送命令 2)命令排队 3)命令执行 4)返回结果 需要注意,慢查询只统计步骤3)的时间,所以没有慢查询并不代表客 户端没有超时问题。 参数配置 slowlog-log-slower-than 单位是微秒(1秒=1000毫秒=1000000微秒),默认值是10000 lowlog-log-slower-than=0会记录所有的命…