printf 函数 实现

本文介绍了如何实现一个自定义的printf函数,增加了对浮点数、负数、保留小数点后几位的功能,并支持四舍五入。同时,还增加了16进制格式的显示,包括小写和大写。通过逆序处理和递归,实现了各种类型的数据格式化输出。
摘要由CSDN通过智能技术生成

printf 函数 实现 修改了部分原链接错误

增加了输入浮点数和双精度的保留小数点后几位位数功能(%.2f ; %.4l)

增加了负数的支持

增加四舍五入

增加16进制格式:%#x  %#X

本文参考以下链接,感谢原创!在他的基础上又进行了追加功能,使更贴近我自己的使用习惯。
原链接:

 printf实现_printf的实现-CSDN博客

printf 函数 实现_printf函数实现-CSDN博客



#include<stdio.h>
#include<stdarg.h>

// unsinged int
void PrintUD(unsigned int Data) 
{
	//逆递归,逆序处理
	if(Data/10!=0)
		PrintUD(Data / 10);
	putchar(Data % 10 +'0');
							 
}

// int
void PrintD(int Data) {
	if(Data<0)
	{
		putchar('-');
		Data = -Data;
	}
	PrintUD(Data);
}
//float
void PrintF(float Data,int len) {

	int Flo;
	int I_Data;
	int power;
	if(Data<0)
	{
		putchar('-');
		Data = -Data;
	}
	//取出整数部分
	I_Data = (int)Data;
	power = 10;
	//float精度是6位(这里说的是32位编译器),首先先将整数部分去掉
	Data -= I_Data;
	while(len --) power *= 10;
	//取精度
	 Flo = ((int)(power * Data) + 5)/10;	// 四舍五入
	 //将后面是0的去掉
	 while(Flo && (Flo%10 == 0)) Flo /= 10; 
	//打印整数
	PrintD(I_Data);
	//分割符
	putchar('.');
	//小数部分
	PrintD(Flo);
	//其实思路是取出小数变成整数然后打印就行了!
}
//double
void PrintLF(double Data,int len) {
	int Flo;
	int I_Data;
	int power;
	if(Data<0)
	{
		putchar('-');
		Data = -Data;
	}
	//取出整数部分
	I_Data = (int)Data;
	power = 10;
	while(len --) power *= 10;
	//float精度是6位(这里说的是32位编译器),首先先将整数部分去掉
	Data -= I_Data;
	//取精度
	 Flo = ((int)(power * Data) + 5)/10;
	 //将后面是0的去掉
	 while(Flo && (Flo%10 == 0)) Flo /= 10; 
	//打印整数
	PrintD(I_Data);
	//分割符
	putchar('.');
	//小数部分
	PrintD(Flo);
	//其实思路很简单,就是取出小数变成整数然后打印就行了!
}
//char
void PrintC(char C) {
	putchar(C);
}
//char*
void PrintStr(const char* Str) {
	while (*Str != '\0') {
		putchar(*Str++);
	}
}
//0x
void PrintX(unsigned long Num, int Base) {
	//判断递归是否小于0
	if (Num <= 0) {
		return;
	}
	//逆序递归
	PrintX(Num / Base, Base);
	//取权值余,这是自然数转进制字符的一种表达式
	putchar("0123456789abcdef"[Num%Base]);
}
void PrintP(unsigned int  num) {		
	PrintX(num, 16);
}

void PrintXsmall(unsigned long Num, int Base) {
	//判断递归是否小于0
	if (Num <= 0) {
		return;
	}
	//逆序递归
	PrintXsmall(Num / Base, Base);
	//取权值余,这是自然数转进制字符的一种表达式
	putchar("0123456789abcdef"[Num%Base]);
}

void PrintXBig(unsigned long Num, int Base) {
	//判断递归是否小于0
	if (Num <= 0) {
		return;
	}
	//逆序递归
	PrintXBig(Num / Base, Base);
	//取权值余,这是自然数转进制字符的一种表达式
	putchar("0123456789ABCDEF"[Num%Base]);
}

//Printf
int My_Printf(char* ForMat, ...) {
	char Line;
	int num = 0;            // 打印字符数量
	int len = 0;	        // 默认精度

	va_list va_l;           // 可变参数列表
	va_start(va_l, ForMat); 
		

	//获取首字符
	 Line = *ForMat;
	while (Line != '\0') {//终结字符
		if (Line == '%') {//判断是否遇到格式符号
			Line = *++ForMat;//遇到的话递增判断后面的字符是什么
AA:			switch (Line) {    //校验
			case 'c':    //char
				PrintC(va_arg(va_l, char));    //传递参数
				break;
			case 's'://str
				PrintStr(va_arg(va_l, char*));
				break;
			case 'd':
				PrintD(va_arg(va_l, int));
				break;
			case 'f'://float 内存中float也是占用8个字节,需要一次性读取8个字节才能读到正确的值,
				if(len == 0)len = 6;
				PrintF(va_arg(va_l, double),len);
				break;
			case 'l'://double
				if(len == 0) len = 9;
				PrintLF(va_arg(va_l, double),len);
				break;
			case 'p':
				PrintP(va_arg(va_l, unsigned int ));
				break;
			case 'o'://打印八进制
				PrintX(va_arg(va_l, int), 8);
				break;
			case 'x'://打印十六进制
				PrintXsmall(va_arg(va_l, int), 16);
				break;
			case 'X'://打印十六进制
				PrintXBig(va_arg(va_l, int), 16);
				break;
			case '.'://.2f 
				Line = *++ForMat;
				if(Line > '0'&& Line <= '9') len = Line - '0';
				Line = *++ForMat;
				goto AA;
            case '#':
                Line = *++ForMat;
                if(Line == 'x' || Line == 'X')
                {
                    putchar('0');
                    putchar(Line);
                    goto AA;                
                }

                else break;
			default://如果不是任何一个格式,则直接打印
				putchar('%');
				putchar(Line);
				break;
			}
		}
		else {
			putchar(Line);
		}
		Line = *++ForMat;
		++num;
	}
	return num;
}
int main() {
	My_Printf("%d,	%c,	%s,	%.2f,	%.4l,	%#x	%#X\r\n",-1,'a',"hello world",-0.12467,0.323654,0x12ab,0XABCEF123);	
	return 0;
}



  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

laocui1

你的鼓励是我创作的最大动了

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值