[C语言]自己实现sprintf,printf函数

一、要点:

实现sprintf,printf的要点在于不定参数的接收与处理,即va_list的使用,另外使用va_list需要包含stdarg.h头函数,想了解详细用法可以自行查找。

另外就是涉及数据的处理与转换,常用的是整型转字符串,以及各种类型转各种格式的字符串。

二、自己实现的类型转换函数

//整形转字符串
void cc_int2str(char *str,int value)
{char tmp_str[20] = {0};int lidx = 0;char flag = 0;int tmp_val;if(value<0){flag = 1;tmp_val = -value;}else{tmp_val = value;}while(1){if(tmp_val==0){break;}else{tmp_str[lidx++] = 0x30+tmp_val%10;tmp_val = tmp_val/10;}}if(flag){tmp_str[lidx++] = '-';}while(lidx--){*str++ = tmp_str[lidx];}*str = 0;
}
//整形转16进制字符串
void cc_int2hexstr(char *str,int value)
{char tmp_str[20] = {0};int lidx = 0;char flag = 0;int tmp_val;if(value<0){flag = 1;tmp_val = -value;}else{tmp_val = value;}while(1){if(tmp_val==0){break;}else{if(tmp_val%16<10){tmp_str[lidx++] = 0x30+tmp_val%16;}else{tmp_str[lidx++] = 0x40+(tmp_val%16-9);}tmp_val = tmp_val/16;}}if(flag){tmp_str[lidx++] = '-';}while(lidx--){*str++ = tmp_str[lidx];}*str = 0;
}
//字符串拷贝函数
int cc_strncpy(char * des,char * src,uint16_t n)
{if(src && des && n){while(n-->0){if(*src){*des++ = *src++;}else{*des++ = *src++;break;}}return 0;}else{return -1;}
}
//字符串拼接函数
int cc_strcat(char * des,char * src)
{if(src && des){while(*des){des++;}while(*src){*des++ = *src++;}*des++ = *src++;return 0;}else{return -1;}
}
//字符串拼接指定长度函数
int cc_strncat(char * des,char * src,uint16_t n)
{if(src && des && n){while(*src){src++;}while(n-->0){if(*src){*des++ = *src++;}else{*des++ = *src++;break;}}return 0;}else{return -1;}
}

三、实现sprintf函数

//记得包含 #include "stdarg.h"void cc_sprintf(char * des,const char *format, ...) {char tmp_str[20] = {0};va_list args;va_start(args, format);*des = 0;while (*format) {switch (*format) {case '%':++format;switch (*format) {case 'd': {int val = va_arg(args, int);cc_int2str(tmp_str,val);cc_strcat(des,tmp_str);break;}case 'x': {int val = va_arg(args, int);cc_int2hexstr(tmp_str,val);cc_strcat(des,tmp_str);break;}case 's': {char *str = va_arg(args, char *);cc_strcat(des,str);break;}default:cc_strcat(des,"%");if (*format) {tmp_str[0] = *format;tmp_str[1] = 0;cc_strcat(des,tmp_str);}break;}break;default:tmp_str[0] = *format;tmp_str[1] = 0;cc_strcat(des,tmp_str);break;}++format;}va_end(args);
}

四、实现printf函数

//记得包含 #include "stdarg.h"
//代码主要针对单片机平台,其他平台请自行修改pchar函数//串口初始化
void Debug_UartCfg(void)
{rcu_periph_clock_enable(RCU_GPIOA);gpio_init(GPIOA,GPIO_MODE_AF_PP,GPIO_OSPEED_50MHZ,GPIO_PIN_9);gpio_init(GPIOA,GPIO_MODE_IN_FLOATING,GPIO_OSPEED_50MHZ,GPIO_PIN_10);rcu_periph_clock_enable(RCU_USART0);usart_deinit(USART0);usart_baudrate_set(USART0,115200);usart_stop_bit_set(USART0,USART_STB_1BIT);usart_word_length_set(USART0,USART_WL_8BIT);usart_parity_config(USART0,USART_PM_NONE);usart_hardware_flow_rts_config(USART0, USART_RTS_DISABLE);usart_hardware_flow_cts_config(USART0, USART_CTS_DISABLE);usart_transmit_config(USART0, USART_TRANSMIT_ENABLE);usart_enable(USART0);
}int pchar(char c)
{while(!usart_flag_get(USART0,USART_FLAG_TBE));usart_data_transmit(USART0,c);while(!usart_flag_get(USART0,USART_FLAG_TC));return 0;
}int putstr(char * c)
{while(*c){pchar(*c++);}return 0;
}void cc_printf(const char *format, ...) {char tmp_str[20] = {0};va_list args;va_start(args, format);while (*format) {switch (*format) {case '%':++format;switch (*format) {case 'd': {int val = va_arg(args, int);int2str(tmp_str,val);putstr(tmp_str);break;}case 'x': {int val = va_arg(args, int);cc_int2hexstr(tmp_str,val);putstr(tmp_str);break;}case 's': {char *str = va_arg(args, char *);putstr(str);break;}default:pchar('%');if (*format) {pchar(*format);}break;}break;default:pchar(*format);break;}++format;}va_end(args);
}

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

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

相关文章

Redis的集群的搭建

1、为什么要搭建Redis集群 Redis 集群能够提供高可用性、高性能、扩展性和数据安全性&#xff0c;适用于各种需要高速缓存和数据存储的复杂应用场景 2、Redis的集群模式 主从模式哨兵模式区中心化模式 3、主从模式 redis主从模式表示一个主节点跟若干个从节点。主节点可以…

矿井水絮凝沉淀一体机处理效果高

诸城市鑫淼环保小编带大家了解一下矿井水絮凝沉淀一体机处理效果高 矿井废水的成分主要是悬浮物和可溶性无机物&#xff0c;还含少量的废机油、乳化油、废坑木腐烂物、井下粪便等有机污染物。 悬浮物SS的特点&#xff1a;含量变化范围很大&#xff0c;可以从几百到几千甚至上万…

VMware 上安装 CentOS 7 教程 (包含网络设置)

**建议先看一些我安装VMware的教程&#xff0c;有些网络配置需要做一下 1.打开VMware&#xff0c;创建虚拟机 2.勾选自定义&#xff0c;点击下一步 3.点击下一步 4.勾选“稍后安装操作系统”&#xff0c;点击下一步 5.勾选linux&#xff0c;勾选centos7&#xff0c;点击下一步…

AH1405芯片的应用领域有哪些?sot23-5封装ic

1405芯片是一种SOT23-5封装的降压转换器&#xff0c;以其出色的性能和广泛的应用领域&#xff0c;成为电子设计中的热门选择。本文将详细介绍1405芯片的技术特点以及其在不同领域的应用情况。 技术特点 1. 宽输入电压范围 1405芯片能够接受从6V至40V的输入电压&#xff0c;这…

汽车绝缘检测详细设计

粘连检测原理 粘连检测&#xff1a; 目的&#xff1a;检测继电器、开关或电气触点是否因故障而保持在接通或断开的状态。工作原理&#xff1a; 正常操作&#xff1a;继电器或开关在正常操作时会周期性地开闭。开闭过程中会有明显的电流和电压变化。粘连状态&#xff1a;如果继…

Vuex数据持久化实现

版本&#xff1a;vue 3.4.29 vuex4.1.0 1. 出现的问题 当我使用 vuex 作为状态管理组件来存储用户的一些信息之后&#xff0c;发现从/login 页面跳转到/home 界面后拿不到vuex信息。 之后查阅资料了解&#xff0c;当切换路由后&#xff0c;vue 会重新渲染&#xff0c;而vuex 也…

实战机器学习--决策树分类器在蘑菇分类中的应用

数据集&#xff1a;https://pan.quark.cn/s/4d3526600c0c 在机器学习领域&#xff0c;图像分类是一个常见的任务&#xff0c;尤其是在自然语言处理和生物识别等领域。本文将通过一个简单的例子&#xff0c;展示如何使用Python和一些流行的库来实现蘑菇的分类&#xff0c;区分可…

docker 部署 LaTeX 环境

docker 部署 LaTeX 环境 需求表述部署步骤环境补丁&#xff08;解决 picins.sty 缺失问题&#xff09; 同步发布在个人笔记docker 部署 LaTeX 环境 需求表述 想做一个项目&#xff0c;需要一个 LaTeX 的中文环境&#xff0c;由于习惯了在服务器上用 docker 部署环境&#xff0…

pgsql的update语句在set里进行字段的运算 SET sort = sort +1

一、场景 需求&#xff1a;version 版本字段是记录数据更新的次数&#xff0c;新增时自动填充 version1 ,每更新一次数据 version就自增1。项目里单表插入和更新要手写update语句进行插入和更新。 –表中int4类型的字段 version 是1时&#xff0c;由1变成2 – version 是null…

【Linux】信号(signal)

目录 一、信号概念&#xff1a; 二、信号的常见状态&#xff1a; 信号递达&#xff1a; 信号未决&#xff1a; 阻塞信号&#xff1a; 忽略信号&#xff1a; 信号在内核中的表示&#xff1a; 三、信号相关函数&#xff1a; sigset_t &#xff08;类型&#xff09;&…

二、QGroundControl开发环境搭建

文章目录 环境列表QGC源码下载编译 环境列表 QGC GithubPX4-AutopilotQt 5.15Ubuntu20.04 QGC源码下载编译 官网下载指令 如下 // Clone the repo (or your fork) including submodules: git clone --recursive -j8 https://github.com/mavlink/qgroundcontrol.git // Upda…

Axure中继器实战篇:让数据展示和交互设计更上一层楼!

Axure中继器实战篇:让数据展示和交互设计更上一层楼! 前言 经过了前两章的学习,接下来我们去模拟的实际场景开启实战篇,以下是界面 1.前期准备 前期把页面准备好后,给中继器的每个单元格命名为了方便数据绑定的操作。 为了演示我准备了几十行数据,建议也多准备一点。…

后端返回一个图片链接,前端如何实现下载功能?

纯原创文章&#xff0c;转载请说明来源。 一、背景 要实现一个下载功能&#xff0c;后端直接返回了一个图片的地址https://xxxxx/pic.jpg。如果我们直接通过window.open(url, _blank) 的方式去下载这个图片&#xff0c;会发现 Chrome 浏览器会对这个图片进行预览&#xff0c;…

魅族手机怎么录屏?详细步骤助你轻松上手

“有人知道魅族手机怎么录屏吗&#xff0c;最近我在准备一些教学视频&#xff0c;急需用到手机的录屏功能来记录操作过程&#xff0c;但遗憾的是&#xff0c;我翻遍了设置也没能找到录屏的开关。所以&#xff0c;我在这里想问问大家&#xff0c;魅族手机是如何启动录屏功能的&a…

【PyTorch】图像多分类项目部署

【PyTorch】图像多分类项目 【PyTorch】图像多分类项目部署 如果需要在独立于训练脚本的新脚本中部署模型&#xff0c;这种情况模型和权重在内存中不存在&#xff0c;因此需要构造一个模型类的对象&#xff0c;然后将存储的权重加载到模型中。 加载模型参数&#xff0c;验证模型…

Sftp和ftp 区别、工作原理

Sftp的工作原理&#xff1a; SFTP的工作原理基于SSH协议&#xff0c;通过加密连接和安全认证来保障文件传输的安全性。 SFTP&#xff08;SSH File Transfer Protocol&#xff09;是一个确保数据在传输过程中安全的协议&#xff0c;它通过为传输的数据提供加密保护和对用户…

Docker重启策略和缩小镜像体积

目录 Docker重启策略 命令格式 命令选项 Docker缩小镜像体积 Docker重启策略 命令格式 docker run --restartno|always|on-failure|unless-stopped .... 命令选项 no&#xff1a;不管容器是正常退出还是异常退出&#xff0c;都不会重启容器。默认策略。always&#xf…

Java面试锦集 之 一、Java基础(1)

一、Java基础&#xff08;1&#xff09; 1.final 关键字的作用&#xff1f; 修饰变量&#xff1a; 一旦被赋值&#xff0c;就不能再被修改&#xff0c;保证了变量值的稳定性。 例&#xff1a; final int NUMBER 10; //之后就不能再改变 NUMBER 的值了。修饰方法&#xff1a;…

图解 HDFS 架构 |读写过程

HDFS HDFS 全称 Hadoop Distributed File System&#xff0c;是一个分布式文件系统。HDFS&#xff08;Hadoop Distributed File System&#xff09;是 Apache Hadoop 生态系统的一部分&#xff0c;它是一个分布式文件系统&#xff0c;用于存储和处理大规模数据集。HDFS 专门设…

【学习笔记】子集DP

背景 有一类问题和子集有关。 给你一个集合 S S S&#xff0c;令 T T T 为 S S S 的超集&#xff0c;也就是 S S S 所有子集的集合&#xff0c;求 T T T 中所有元素的和。 暴力1 先预处理子集的元素和 A i A_i Ai​&#xff0c;再枚举子集。 for(int s0; s<(1<…