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

news2024/11/24 23:30:10

目录

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() 从固定字符串中解析数据,并将结果输出。程序运行结果如下:

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

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

相关文章

操作系统教材第6版——个人笔记6

3.3.4 页面调度 页面调度 当主存空间已满而又需要装入新页时&#xff0c;页式虚拟存储管理必须按照一定的算法把已在主存的一些页调出去 #主存满加新&#xff0c;把已在主存一些页调出选择淘汰页的工作称为页面调度 选择淘汰页的算法称为页面调度算法 页面调度算法设计不当&a…

【递归、搜索与回溯】递归、搜索与回溯准备+递归主题

递归、搜索与回溯准备递归主题 1.递归2.搜索3.回溯与剪枝4.汉诺塔问题5.合并两个有序链表6.反转链表7.两两交换链表中的节点8.Pow(x, n)-快速幂&#xff08;medium&#xff09; 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你…

解决Windows Hosts 文件因为权限无法修改的问题

如何修改 Windows Hosts 文件并添加域名映射 在日常工作中&#xff0c;可能需要修改 Windows 的 hosts 文件&#xff0c;以将特定的域名映射到指定的 IP 地址。本文介绍三种方法来完成这一任务&#xff1a;直接手动编辑 hosts 文件&#xff0c;使用批处理文件自动完成任务&…

哈默纳科Harmonic谐波减速机应用领域有哪些

在制造设备中&#xff0c;精确控制速度与位置的需求日益凸显&#xff0c;这为谐波减速机的广泛应用提供了广阔的舞台。哈默纳科Harmonic谐波减速机以结构紧凑、高精度、高刚度、高可靠性、便于安装维护等优势&#xff0c;在工业机器人和自动化系统中发挥着举足轻重的作用。 一、…

如何调用地方天地图?

我们在《如何申请自己的专属天地图&#xff1f;》一文中&#xff0c;为大家分享了如果申请专属天地图&#xff0c;并在水经微图&#xff08;以下简称“微图”&#xff09;中加载的具体方法。 于是&#xff0c;就有朋友问如何调地方用天地图。 现在&#xff0c;我们就以四川地…

六位一线AI工程师总结大模型应用摸爬滚打一年的心得,网友:全程高能!

六位一线AI工程师和创业者&#xff0c;把在大模型应用开发上摸爬滚打一整年的心得&#xff0c;全&#xff01;分&#xff01;享&#xff01;了&#xff01; &#xff08;奇怪的六一儿童节大礼包出现了&#xff09; 这篇干货长文&#xff0c;一时间成为开发者社区热议的话题。…

2024年几款优秀的SQL IDE优缺点分析

SQL 工具在数据库管理、查询优化和数据分析中扮演着重要角色。 以下是常见的 SQL 工具及其优缺点。 1. SQLynx 优点&#xff1a; 智能代码补全和建议&#xff1a;采用AI技术提供高级代码补全、智能建议和自动错误检测&#xff0c;大幅提高编写和调试SQL查询的效率。跨平台和…

蓝桥杯物联网竞赛_STM32L071_19_输出方波信号(PWM)

国赛考了一个方波&#xff0c;第一次考这个&#xff0c;连个示波器都没有 CUBMX配置&#xff1a; 按上述配置刚好是32MHZ / 32 / 100 10KHZ 理论&#xff1a; 频率&#xff1a;就是一秒钟能产生多少个脉冲&#xff0c;如下图: 这算是一个脉冲&#xff0c;1KHZ说明一秒钟产生…

源码发布Quantlab4.2,Deap因子挖掘|gplearn做不到的咱们也能做。(代码+数据)

原创文章第552篇&#xff0c;专注“AI量化投资、世界运行的规律、个人成长与财富自由"。 又到了星球发布代码的日子&#xff1a; 更新说明&#xff1a;1、Deap做因子挖掘的框架使用。值得说明的是&#xff0c;源码级别&#xff0c;并非产品级&#xff0c;不能指望输入一堆…

降噪是什么意思?视频如何降噪?一文了解全部

在视频制作的过程中&#xff0c;我们经常会遇到噪音问题&#xff0c;这些噪音可能来自拍摄环境、录制设备或其他源头。然而&#xff0c;对于初学者来说&#xff0c;降噪是什么意思&#xff0c;以及如何有效地在视频中进行降噪可能是一些疑惑的问题。本文将深入解释降噪的概念&a…

Mat的lambda方式像素高效遍历(C++11)

Mat的lambda方式像素高效遍历&#xff08;C11&#xff09; 文章目录 Mat的lambda方式像素高效遍历&#xff08;C11&#xff09;前言一、Mat的lambda方式像素高效遍历二、代码实现总结 前言 图像遍历是图像处理中的经典操作&#xff0c;快速高效的进行像素遍历对性能的提升至关…

[AI OpenAI] 提取GPT-4中的概念

总结&#xff1a; 研究人员采用新的可扩展方法&#xff0c;将GPT-4的内部表示分解为1600万个通常可解释的模式&#xff0c;这些模式被称为“特征”&#xff0c;目的是提高语言模型的透明度和可解释性。通过使用稀疏自编码器&#xff0c;研究人员能够识别与特定概念相关的特征&…

《今日科技》是什么级别的期刊?是正规期刊吗?能评职称吗?

问题解答 问&#xff1a;《今日科技》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊 问&#xff1a;《今日科技》是什么级别的&#xff1f; 答&#xff1a;省级。主管单位&#xff1a;浙江省科学技术厅 主办单位&#xff1a;浙江省…

免费分享一套SpringBoot+Vue校园论坛(微博)系统【论文+源码+SQL脚本】,帅呆了~~

大家好&#xff0c;我是java1234_小锋老师&#xff0c;看到一个不错的SpringBootVue校园论坛(微博)系统&#xff0c;分享下哈。 项目视频演示 【免费】SpringBootVue校园论坛(微博)系统 Java毕业设计_哔哩哔哩_bilibili【免费】SpringBootVue校园论坛(微博)系统 Java毕业设计…

Cesium401 (Unauthorized)https://api.cesium.com/v1/assets/2/endpoint未授权问题

目录 前言1.原因分析2.解决问题1.禁用默认的imageryProvider2.禁用图层切换3.移除所有默认图层4.使用自己的地形(可选) 3.最终解决方案4.总结 前言 在初始化Cesium的Viewer以后&#xff0c;Viewer会自动去访问Cesium官网的资源&#xff0c;如果访问不到官网的资源&#xff0c;就…

parseInt函数

貌似遇到问题了&#xff0c;在Java中&#xff0c;parseInt方法是java.lang.Integer类的一个静态方法&#xff0c;它用来将字符串转换为基本数据类型int。如果字符串不能被解析为有效的整数&#xff0c;parseInt会抛出一个NumberFormatException。 原来是取整串转换&#xff0c;…

Lab_ Exploiting an API endpoint using documentation

https://portswigger.net/web-security/learning-paths/api-testing/ 开局一个页面 打开代理和burp&#xff0c;查看功能点&#xff0c;然后看HTTPhistory 然后使用题目已知的账号去登录一下 My account 登录 然后发现 /api 路径 那么我们访问一下 URL/api &#xff0c;发现…

宋仕强论道 之 AI(人工智能)

《宋仕强论道 之 AI&#xff08;人工智能&#xff09;如何赋能新质生产力》于6月3日由新华瞭望网首发后&#xff0c;被环球科技新闻网等多家媒体转载&#xff1b;随后又分别以《宋仕强论道 之 AI如何赋能新质生产力》《宋仕强&#xff1a;AI赋能新质生产力的理论探索与实践路径…

有关大学的搜题软件?六个不限次的公众号和软件分享啦 #其他#职场发展

有些同学虽然喜欢刷题&#xff0c;但是如果参考答案遗失、找不到参考答案&#xff0c;导致做好的题目无法校对&#xff0c;就会比较烦恼了。不过不用担心&#xff0c;今天就给大家分享一些超好用的搜题工具 1.彩虹搜题 这是个老公众号了 它不仅可以查到大学题目&#xff0c;…

【机器学习】朴素贝叶斯算法及其应用探索

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 朴素贝叶斯算法及其应用探索引言1. 朴素贝叶斯基本概念1.1 贝叶斯定理回顾1.2 朴…