2019.02.01更新:经同学提醒,myprintf函数应有返回值为输出的字符数。

期末的大作业,手写一个myprintf函数,支持如下一些操作。

也就是  % -(负号控制左右对齐) 数(控制字段宽). 数(控制精度) ?(字符,控制类型)

我实现的话就是按上面的实现的,说一下这个简化版存在的问题(简化的地方):

1)%d %i %o %x %X %u %c 这些都默认后面输入的是int,所以long long其实没有用。

2)支持最大精度<=30,如果有需要请更改PRECISION

myprintf默认四舍五入(rounding_off函数实现)

如果发现错误,请指出,谢谢大家啦!

 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<stdarg.h> #define N 110
#define eps 1e-16
#define INF 1e9
#define PRECISION 30 int maxx(int x,int y){return x>y ? x:y;}
void swapp(char *x,char *y){char t;t=*x;*x=*y;*y=t;}
int find_int_type(int int_type,char ch);
void change_int_type_to_char(int x,int int_type,char *s,int *sl,int *minus);
void print_int_regardless_type(char *s,int *sl,int minus,int Justify_type,int min_width,int precision);
void print_int(int x,int Justify_type,int min_width,int precision,int int_type);
void print_string(char *s,int Justify_type,int min_width,int precision);
int is_g_or_G(char double_type){return (double_type == 'g' || double_type=='G');}
void rounding_off(char *s,int *sl,int *ml,int precision);
void print_double_e_or_E(char *s,int sl,int exponent,int minus,int Justify_type,int min_width,int precision,char double_type);
void print_double_f(char *s,int sl,int ml,int minus,int Justify_type,int min_width,int precision);
void print_double(double x,int Justify_type,int min_width,int precision,char double_type);
int myprintf(const char *format,...); int main()
{
// freopen("a.out","w",stdout);
int a=;
double b=9.9734567;
int count=;
myprintf("%\n");
myprintf("%15e%15e\n",-0.0000123,123.123);printf("%15e%15e\n",-0.0000123,123.123);
myprintf("%f\n",0.0000123);printf("%f\n",0.0000123);
myprintf("%.1E\n",b);printf("%.1E\n",b);
myprintf("%e\n",0.0000123);printf("%e\n",0.0000123);
myprintf("%15.8g\n",0.000012346789);printf("%15.8g\n",0.0000123456789);
myprintf("%5d%10d\n",a,a);printf("%5d%10d\n",a,a);
myprintf("%10.5d%10.5d\n",a,a);printf("%10.5d%10.5d\n",a,a);
myprintf("%15.10hd%15.10ld\n",count,count);printf("%15.10hd%15.10ld\n",count,count);
myprintf("%5o\n",a);printf("%5o\n",a);
myprintf("%f\n",b);printf("%f\n",b);
myprintf("%15f%20.10f\n",-b,-b);printf("%15f%20.10f\n",-b,-b);
myprintf("%15g\n",0.0000123);printf("%15g\n",0.0000123);
myprintf("%15e%15E%15g%15g\n",-b,b,b,0.0000123);printf("%15e%15E%15g%15g\n",-b,b,b,0.0000123);
myprintf("%15g\n",0.0000123);printf("%15g\n",0.0000123);
myprintf("%-15.10x%10.10X\n",count);printf("%-15.10x%10.10X\n",count);
myprintf("%10.5s\n%c\n","asdfghjkl",'a');printf("%10.5s\n%c\n","asdfghjkl",'a');
myprintf("\x41\101 \\ \r\n");printf("\x41\101 \\ \r\n");
unsigned int d = ;
myprintf("%.10u\n",d);printf("%.10u\n",d);
int *p;
myprintf("%p\n",p);printf("%p\n",p);
return ;
} int find_int_type(int int_type,char ch)
{
if(ch=='d' || ch=='i') return int_type;
if(ch=='o') return ;
if(ch=='x') return ;
if(ch=='X') return ;
if(ch=='u') return int_type+;
} void change_int_type_to_char(int x,int int_type,char *s,int *sl,int *minus)
{
*sl=;
switch(int_type)
{
case :{//int
int y=(int)x;if(y<) *minus=,y=-y;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//unsigned int
unsigned int y=(unsigned int)x;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//short
short int y=(short int)x;if(y<) *minus=,y=-y;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//unsigned short
unsigned short int y=(unsigned short int)x;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//long int
long int y=(long int )x;if(y<) *minus=,y=-y;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//unsigned long int
unsigned long int y=(unsigned long int)y;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//o
int y=(int )x;
while(y) s[(*sl)++]=(y%)+'',y/=;
break;
}
case :{//x
int y=(int)x;
while(y) s[(*sl)++]=((y%)>=) ? (y%)-+'a' : (y%)+'',y/=;
break;
}
case :{//X
int y=(int)x;
while(y) s[(*sl)++]=((y%)>=) ? (y%)-+'A' : (y%)+'',y/=;
break;
}
}
} void print_int_regardless_type(char *s,int *sl,int minus,int Justify_type,int min_width,int precision)
{
while(precision<INF && *sl<precision) s[(*sl)++]='';
if(minus) s[(*sl)++]='-';
int space=min_width-*sl; if(Justify_type==)//right
for(int i=;i<=space;i++) putchar(' ');
for(int i=(*sl)-;i>=;i--) putchar(s[i]);
if(Justify_type==)//left
for(int i=;i<=space;i++) putchar(' ');
} void print_int(int x,int Justify_type,int min_width,int precision,int int_type)
{
int minus=(x<) ? :;
char *s=(char *)malloc(N*sizeof(char));
int *sl=(int *)malloc(sizeof(int));
change_int_type_to_char(x,int_type,s,sl,&minus);
print_int_regardless_type(s,sl,minus,Justify_type,min_width,precision);
free(s);
free(sl);
} void print_string(char *s,int Justify_type,int min_width,int precision)
{
int sl=strlen(s);
if(sl > precision) sl=precision;
int space=min_width-sl; if(Justify_type==)//right
for(int i=;i<=space;i++) putchar(' ');
for(int i=;i<sl;i++) putchar(s[i]);
if(Justify_type==)//left
for(int i=;i<=space;i++) putchar(' ');
} void rounding_off(char *s,int *sl,int *ml,int precision)//四舍五入
{
if(s[(*ml)+precision]<='') return;
s[(*ml)+precision-]++;
for(int i=(*ml)+precision-;i>=;i--) s[i-]+=(s[i]-'')/,s[i]=(s[i]-'')%+'';
if(s[]>'')
{
(*sl)++;(*ml)++;
for(int i=(*ml)+precision;i>=;i--) s[i]=s[i-];
s[]=(s[]-'')/+'';
s[]=(s[]-'')%+'';
}
} void print_double_e_or_E(char *s,int sl,int exponent,int minus,int Justify_type,int min_width,int precision,char double_type)
{
int space=min_width-(minus++precision+++);
if(precision) space--;//'.' if(Justify_type==)//right
for(int i=;i<=space;i++) putchar(' ');
if(minus) putchar('-');
putchar(s[]);
if(precision) putchar('.');
for(int i=;i<=precision;i++)
{
if(i>=sl && is_g_or_G(double_type)) break;
putchar((i<sl) ? s[i] : '');
}
putchar(is_g_or_G(double_type) ? double_type+'e'-'g' : double_type);
if(exponent>=) putchar('+');
else putchar('-'),exponent*=-;
putchar(exponent/+'');putchar((exponent/)%+'');putchar(exponent%+'');
if(Justify_type==)//left
for(int i=;i<=space;i++) putchar(' ');
} void print_double_f(char *s,int sl,int ml,int minus,int Justify_type,int min_width,int precision)
{
int space=min_width-(minus+ml+precision);
if(precision) space--;//'.'
if(Justify_type==)//right
for(int i=;i<=space;i++) putchar(' ');
if(minus) putchar('-');
for(int i=;i<ml;i++) putchar(s[i]);
if(precision) putchar('.');
for(int i=ml;i<=ml-+precision;i++) putchar((i<sl) ? s[i]:'');
if(Justify_type==)//left
for(int i=;i<=space;i++) putchar(' ');
} //m.ddddd
void print_double(double x,int Justify_type,int min_width,int precision,char double_type)
{
if(precision==INF) precision=;
int zero=(fabs(x) < eps);
int minus=(x<) ? :;x=fabs(x);
char *s=(char *)malloc(N*sizeof(char));
int sl=,ml=,y=(int)x;x-=y;
if(y==) s[sl++]='';
while(y) s[sl++]=y%+'',y/=;
for(int i=;i<=(sl-)/;i++) swapp(&s[i],&s[sl--i]);
ml=sl;
while(sl<=ml+PRECISION) s[sl++]=(int)(x*)+'',x=x*-(int)(x*);
//f
if(double_type=='f')
{
rounding_off(s,&sl,&ml,precision);
print_double_f(s,sl,ml,minus,Justify_type,min_width,precision);
}
else//e E g G
{
int st=,ssl=,exponent=ml-;
char *ss=(char *)malloc(N*sizeof(char));
while(!zero && s[st]=='') st++,exponent--,s[sl++]='';
for(int i=st;i<sl;i++) ss[ssl++]=s[i]; if(double_type=='e' || double_type=='E' ||
(is_g_or_G(double_type) && (exponent < - || exponent >=precision)))
{
ml=;
if(is_g_or_G(double_type))
{
if(precision) precision--,ssl--;
while(precision && ss[ml+precision-]=='') precision--;
}
int mml=;
rounding_off(ss,&ssl,&mml,precision);
if(mml==) exponent++;
print_double_e_or_E(ss,ssl,exponent,minus,Justify_type,min_width,precision,double_type);
}
else
{
precision-=ml;sl-=ml;
rounding_off(s,&sl,&ml,precision);
while(precision && s[ml+precision-]=='') precision--;
print_double_f(s,sl,ml,minus,Justify_type,min_width,precision);
}
free(ss);
}
free(s);
} int myprintf(const char *format,...)
{
char ch;
int arg_int;
double arg_double;
char *arg_str;
void *arg_p;
va_list ap;
va_start(ap,format); while((ch = *format++)!='\0')
{
if(ch!='%') {putchar(ch);continue;}
//ch = '%' *format = '\0'
if(*format=='\0' || *format=='%') {putchar('%');continue;} int Justify_type=,min_width=,precision=INF,int_type=,ok=;
if(*format=='-') Justify_type=,format++;
while(*format>='' && *format<='') min_width=min_width*+*format-'',format++;
if(*format=='.')
{
format++;precision=;
while(*format>='' && *format<='') precision=precision*+*format-'',format++;
}
if(*format=='h') int_type=,format++;
if(*format=='l') int_type=,format++; if(*format=='d' || *format=='i' || *format=='o' || *format=='x' || *format=='X' || *format=='u')
{
ok=;arg_int=va_arg(ap,int);
print_int(arg_int,Justify_type,min_width,precision,find_int_type(int_type,*format));
}
if(*format=='c')
{
ok=;arg_int=va_arg(ap,int);
putchar(arg_int);
}
if(*format=='s')
{
ok=;arg_str=va_arg(ap,char *);
print_string(arg_str,Justify_type,min_width,precision);
}
if(*format=='f' || *format=='e' || *format=='E' || *format=='g' || *format=='G')
{
ok=;arg_double=va_arg(ap,double);
print_double(arg_double,Justify_type,min_width,precision,*format);
}
if(*format=='p')
{
ok=;arg_p=va_arg(ap,void *);
arg_int=(int)arg_p;
precision=;//默认地址为8位,若机器地址不为8位可更改此处。
print_int(arg_int,Justify_type,min_width,precision,);
}
if(!ok) {putchar('%');format--;}//ch=='%'
format++;
}
va_end(ap);
}

手写简化版printf函数的更多相关文章

  1. 依据ECMA规范,手写一个bind函数

    Function.prototype.bind 函数,参见ECMA规范地址 如题,这次来实现一个boundFunction函数,不挂载在Function.prototype上,而是一个单独声明的函数. ...

  2. 【OpenCV学习笔记】之六 手写图像旋转函数---万丈高楼平地起

    话说,平凡之处显真格,这一点也没错!  比如,对旋转图像进行双线性插值,很简单吧?  可,对我,折腾了大半天,也没有达到预期效果!  尤其是三个误区让我抓瞎好久: 1,坐标旋转公式.   这东西,要用 ...

  3. 手写事件代理函数 (Delegated function)

    ‘手写 ’ 这个词 ,面试是不是听过无数遍呢 ! 今天我们来手写一个这样的事件委托函数 => function( parent, selector, type ,  handle)  {} 你需 ...

  4. 前端面试手写代码——JS函数柯里化

    目录 1 什么是函数柯里化 2 柯里化的作用和特点 2.1 参数复用 2.2 提前返回 2.3 延迟执行 3 封装通用柯里化工具函数 4 总结和补充 1 什么是函数柯里化 在计算机科学中,柯里化(Cu ...

  5. cs224d 作业 problem set2 (一) 用tensorflow纯手写实现sofmax 函数,线性判别分析,命名实体识别

    Hi Dear Today we will use tensorflow to implement the softmax regression and linear classifier algor ...

  6. 手写Function.bind函数

    if(!Function.prototype.bind){ Function.prototype.bind = function(oThis){ if(typeof this !=="fun ...

  7. 手写简化版SpringBoot

    Springboot项目全部依赖注解的,web工程是如何启动的 1 首先引入了Tomcat依赖,然后用java代码启动Tomcat容器,默认Tomcat版本是8.5版本 2 Tomcat是实现了ser ...

  8. 手写map, filter函数

    function map(arr, fn) { let newArr = []; for (let i = 0; i < arr.length; i++) { newArr[i] = fn(ar ...

  9. 22 道高频 JavaScript 手写面试题及答案

    实现防抖函数(debounce) 防抖函数原理:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时. 那么与节流函数的区别直接看这个动画实现即可. 手写简化版: // 防抖函数 cons ...

随机推荐

  1. Sprint2-2.0

    1.开始一个新的冲刺: 起止:2016.6.1~2016.6.14 按照以下过程进行 ProductBacklog:继续向下细化 Sprint 计划会议:确定此次冲刺要完成的目标 Sprint Bac ...

  2. 【Web Shell】- 技术剖析中国菜刀 - Part II

    在第一部分,简单描述了中国菜刀的基本功能.本文我将剖析中国菜刀的平台多功能性.传输机制.交互模式和检测.我希望通过我的讲解,您能够根据您的环境检测出并清除它. 平台 那么中国菜刀可以在哪些平台上运行? ...

  3. Centos7 django+uwsgi+nginx+python3.6.8部署

    安装依赖 yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-d ...

  4. [知乎]SSD的延迟

    以及一些SSD的性能数据

  5. poj 2942 Knights of the Round Table(点双连通分量+二分图判定)

    题目链接:http://poj.org/problem?id=2942 题意:n个骑士要举行圆桌会议,但是有些骑士相互仇视,必须满足以下两个条件才能举行: (1)任何两个互相仇视的骑士不能相邻,每个骑 ...

  6. Python动态规划求解最长递增子序列(LIS)

    原始代码错误,移步博客查看O(N^2)及优化的O(N*logN)的实现:每天一道编程题--最长递增子序列

  7. 图像分割——graph cuts

    Graph cuts是一种基于图论的方法,它是一种能量优化算法,在计算机视觉领域应用于前景背景分割,立体视觉,抠图等. 这类方法首先使用无向图G=<V,E>表示要分割的图像,V和E分别是顶 ...

  8. 基于c的简易计算器二

    #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> ...

  9. php 关于文件的一些封装好的函数

    <?php //Bytes/Kb/MB/GB/TB/EB /** * 转换字节大小 * @param number $size * @return number */ function tran ...

  10. zabbix短信(阿里云短信平台)与邮件报警

    环境说明 操作系统 centos7 zabbix_server zabbix 4.0.3 python 3.6.5 短信平台 阿里云短信 zabbix_server配置信息 1 [root@cp-hb ...