C语言程序设计:简易版的printf函数实现

简易版的printf函数实现

功能说明

(1)使用putchar函数、va可变参完成printf函数基本功能的实现;
(2)函数说明:

实现对下列数据类型的输出,并返回成功输出打印的字符个数:

  • 整数(正负)的输出;
  • 字符串输出;
  • 浮点数(float、double)输出;
  • 字符输出;

函数实现

#include <stdio.h>
#include <stdarg.h>
#include <limits.h>
#include <inttypes.h>int myprintf(const char *format, ...) {va_list args;va_start(args, format);int char_count = 0; // 记录写入的字符数量while (*format) {if (*format == '%') {format++;switch (*format) {case 'c': {char c = va_arg(args, int);putchar(c);char_count++;break;}case 'd': {int d = va_arg(args, int);if (d == INT32_MIN) {putchar('-');putchar('2');d = 147483648; char_count += 2;} else if (d < 0) {putchar('-');d = -d;char_count++;}int divisor = 1;while (d / divisor >= 10)divisor *= 10;while (divisor > 0) {putchar(d / divisor + '0');d %= divisor;divisor /= 10;char_count++;}break;}case 's': {char *s = va_arg(args, char *);while (*s) {putchar(*s);s++;char_count++;}break;}case 'l': {format++;switch (*format) {case 'l':format++;if (*format == 'd') {long long ll = va_arg(args, long long);if (ll == LLONG_MIN) {putchar('-');putchar('9');ll = 223372036854775808LL; char_count += 2;} else if (ll < 0) {putchar('-');ll = -ll;char_count++;}unsigned long long divisor = 1;while (ll / divisor >= 10)divisor *= 10;while (divisor > 0) {putchar(ll / divisor + '0');ll %= divisor;divisor /= 10;char_count++;}}break;case 'f': {double lf = va_arg(args, double);int int_part = (int)lf;int fract_part = (int)((lf - int_part) * 1000000); if (lf < 0) {putchar('-');lf = -lf;char_count++;}int divisor = 1;while (int_part / divisor >= 10)divisor *= 10;while (divisor > 0) {putchar(int_part / divisor + '0');int_part %= divisor;divisor /= 10;char_count++;}putchar('.');char_count++;divisor = 100000;while (fract_part / divisor == 0) {putchar('0');divisor /= 10;char_count++;}while (divisor > 0) {putchar(fract_part / divisor + '0');fract_part %= divisor;divisor /= 10;char_count++;}break;}}break;}default:putchar(*format);char_count++;}} else {putchar(*format);char_count++;}format++;}va_end(args);return char_count;
}

测试代码

void test_myprintf_v1() {long long big_number = 12345678901234LL;double pi = 3.141592653589793;myprintf("hello word !\n"); myprintf("LONG LONG: %lld\n", big_number);myprintf("FLOAT: %lf\n", pi);myprintf("INT32_MIN: %d\n", INT32_MIN);myprintf("INT32_MAX: %d\n", INT32_MAX);myprintf("LLONG_MIN: %lld\n", LLONG_MIN);myprintf("%c\n", 'A');return ;
}void test_myprintf_v2() {int ret;//打印字符常量printf("System:\n");ret = printf("hello word\n");printf("成功打印:%d\n", ret);printf("MySelf:\n");ret = myprintf("hello word\n");printf("成功打印:%d\n", ret);putchar(10);  //打印整型变量 int a = INT32_MIN, b = INT32_MAX;printf("System:\n");ret = printf("a = %d, b = %d\n", a, b);printf("成功打印:%d\n", ret);printf("MySelf:\n");ret = myprintf("a = %d, b = %d\n", a, b);printf("成功打印:%d\n", ret);putchar(10);//打印字符char c1 = 'a', c2 ='3';printf("System:\n");ret = printf("c1 = %c, c2 = %c\n", c1, c2);printf("成功打印:%d\n", ret);printf("MySelf:\n");ret = myprintf("c1 = %c, c2 = %c\n", c1, c2);printf("成功打印:%d\n", ret);putchar(10);//打印字符串char s1[150] = "adasdc asd as a", s2[150] ="sdadas asda sdaas";printf("System:\n");ret = printf("s1 = %s, s2 = %s\n", s1, s2);printf("成功打印:%d\n", ret);printf("MySelf:\n");ret = myprintf("s1 = %s, s2 = %s\n", s1, s2);printf("成功打印:%d\n", ret);return ;
}int main() {test_myprintf_v2();return 0;
}

运行效果

在这里插入图片描述

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

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

相关文章

在CSDN创作了6个月,我收获了什么?文末送书~

作者主页&#xff1a;阿玥的小东东主页&#xff01; 正在学习&#xff1a;python和C/C 期待大家的关注哦 目录 一次很好的机会&#xff0c;让我开始了CSDN之旅 首先来看看我的几位领路人 创作动力 1W粉丝 在CSDN我收获了什么&#xff1f; 很高的展现量 认证创作者身份 社…

【Linux】系统安全及应用

目录 一、账号安全基本措施 1.系统账号清理 2.密码安全控制 3.历史命令安全管理 4.限制su切换用户 1&#xff09;将信任的用户加入到wheel组中 2&#xff09;修改su的PAM认证配置文件 5.ssh远程登录输入三次密码错误则锁定用户 二、Linux中的PAM安全认证 1.su命令的…

Redis入门到通关之数据结构解析-动态字符串SDS

文章目录 Redis数据结构-动态字符串动态扩容举例二进制安全SDS优点与C语言中的字符串的区别 Redis数据结构-动态字符串 我们都知道 Redis 中保存的Key是字符串&#xff0c;value 往往是字符串或者字符串的集合。可见字符串是 Redis 中最常用的一种数据结构。 不过 Redis 没有…

Android Studio超级详细讲解下载、安装配置教程(建议收藏)

博主介绍&#xff1a;✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神&#xff0c;答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战&#xff0c;深受全网粉丝喜爱与支持✌有…

贪吃蛇游戏实现(VS编译环境)

贪吃蛇游戏 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C语言&#x1f353; &#x1f33c;文章目录&#x1f33c; 0. 前言 1. 游戏背景 2. 实现后游戏画面展示 3. 技术要求 4. Win32 API介绍 4.1 Win32 API 4.2 控制台程序 4.…

Java之类和对象

一面向对象的初步认知 1.什么是面向对象 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成一件事情。用面向对象的思想…

嵌入式物联网实战开发笔记-乐鑫ESP32开发环境ESP-IDF搭建【doc.yotill.com】

乐鑫ESP32入门到精通项目开发参考百例下载&#xff1a; 链接&#xff1a;百度网盘 请输入提取码 提取码&#xff1a;4e33 3.1 ESP-IDF 简介 ESP-IDF&#xff08;Espressif IoT Development Framework&#xff09;是乐鑫&#xff08;Espressif Systems&#xff09;为 ESP 系列…

大型网站系统架构演化实例_2.使用缓存改善网站性能

1.使用缓存改善网站性能 网站访问的特点和现实世界的财富分配一样遵循二八定律&#xff1a;80%的业务访问集中在20%的数据上。既然大部分业务访问集中在一小部分数据上&#xff0c;那么如果把这一小部分数据缓存在内存中&#xff0c;就可以减少数据库的访问压力&#xf…

【Python】自定义修改pip下载模块默认的安装路径

因为电脑下载了Anaconda提供的默认Python 3.9 以及后期下载的python3.10所以在Pychram进行项目开发时&#xff0c;发现一些库怎么导入都导入不了&#xff0c;手动install也是失败&#xff0c;后期在cmd里面发现python以及pip配置有点儿混乱&#xff0c;导致执行命令时&#xff…

碳循环、人类、遥感之间的关联

1. 碳与碳循环 碳是自然界中很常见的一种元素&#xff0c;它以多种形式广泛存在于大气和地壳之中。碳单质很早就被人认识和利用&#xff0c;碳的一系列化合物——有机物是生命的根本。 1.1 自然界中的碳 地球上最大的两个碳库是岩石圈和化石燃料&#xff0c;含碳量约占…

在RISC-V64架构的CV1811C开发板上应用perf工具进行多线程程序性能分析及火焰图调试

CV1811C环境编译 SDK目录结构 . ├── build // 编译目录,存放编译脚本以及各board差异化配置 ├── buildroot-2021.05 // buildroot开源工具 ├── freertos // freertos系统 ├── fsbl // fsbl启动固件,prebuilt形式存在…

Android14 - WindowManagerService之客户端Activity布局

Android14 - WindowManagerService之客户端Activity布局 一、主要角色 WMS作为一个服务端&#xff0c;有多种客户端与其交互的场景。我们以常见的Activity为例&#xff1a; Activity&#xff1a;在ActivityThread构建一个Activity后&#xff0c;会调用其attach方法&#xff0c;…

[docker] volume 补充 环境变量 参数

[docker] volume 补充 & 环境变量 & 参数 这里补充一下 volume 剩下的内容&#xff0c;以及添加参数(ARG) 和 环境变量 ENV 的内容 read only volumes ❯ docker run-p 3000:80--rm--name feedback-app-v feedback:/app/feedback-v "$(pwd):/app"-v /app/…

【C++初阶】vector使用特性 vector模拟实现

1.vector的介绍及其使用 1.1 vector的介绍 vector文档介绍 1. vector是表示可变大小数组的序列容器。 2. 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#…

第24天:安全开发-PHP应用文件管理模块显示上传黑白名单类型过滤访问控制

第二十四天 一、PHP文件管理-显示&上传功能实现 如果被抓包抓到数据包&#xff0c;并修改Content-Type内容 则也可以绕过筛查 正常进行上传和下载 二、文件上传-$_FILES&过滤机制实现 无过滤机制 黑名单过滤机制 使用 explode 函数通过点号分割文件名&#xff0c;…

VTC视频时序控制器原理以及Verilog实现

文章目录 一、前言二、视频时序控制原理三、Verilog实现3.1 代码3.2 仿真以及分析 一、前言 VTC&#xff08;Video Timing Controller&#xff09;是一种用于产生视频时序的控制器&#xff0c;在FPGA图像领域经常用到。Xilinx Vivado 也有专门用于生成视频时序的 IP&#xff0c…

webpack-babel2

浏览器的兼容性问题 浏览器的兼容性问题不知包括随屏幕大小而变化&#xff0c;还包括针对浏览器支持的特性&#xff08;如css特性&#xff0c;js特性&#xff09; 做处理。 目前市场上有很多浏览器&#xff1a;Chrome,Safari,IE,Edge等&#xff0c;要根据它们的市场占有率来决…

vue 对axios二次封装,配置api层,基于mock测试数据

一、初始化环境&#xff08;默认都会安装vue3项目ts&#xff09; 安装mock&#xff1a;全局安装 # 使用 npm 安装 npm install mockjs vite-plugin-mock # 使用 yarn 安装 yarn add mockjs vite-plugin-mock 二、进行配置 在vite.config.ts中进行配置 import { UserConfigEx…

NodeRed节点编辑用于边缘计算和规则引擎,能做带UI界面和业务逻辑的上位机或前端应用吗?

先说结论&#xff0c;可以&#xff0c;但是需要有页面嵌套继承类似的技术&#xff0c;实现页面模块化封装&#xff0c;否则难以实现复杂应用。 相信目光敏锐的人都在关注节点编辑在自身行业的应用&#xff01; NodeRed在边缘计算做数据协议解析、以及物联网平台中作为规则链引…