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. 父元素如果为none,子元素也是看不到的

    1.最近遇到一个问题,就是获取一个子元素的offsetwidth 的值总是为0 .原因是因为把父元素给设置成none了. 2.给元素赋值宽高 div.style.width=330+'px' 要加上p ...

  2. 配置ssh免密码登入

    首先要设置好主机名hostnamectl,然后编辑文件/etc/hosts 192.168.43.9 node0 192.168.43.10 node1 192.168.43.11 node2     ...

  3. Linux进程调度策略的发展和演变(转)

    转发:http://blog.csdn.net/gatieme/article/details/51701149  1 前言 1.1 进程调度 内存中保存了对每个进程的唯一描述, 并通过若干结构与其他 ...

  4. ASP.NET Core 2 学习笔记

    之前的ASP.NET网站,只要把*.html.*.css.*.jpg.*.png.*.js等静态文件放在项目根目录,默认都可以直接被浏览:但ASP.NET Core 小改了浏览静态文件的方式,默认根目 ...

  5. springboot学习笔记-3 整合redis&mongodb

    一.整合redis 1.1 建立实体类 @Entity @Table(name="user") public class User implements Serializable ...

  6. Linux下安装 mongodb

    1.下载 去官网 https://www.mongodb.com  找到对应版本的mongodb 的下载地址 这样的: https://fastdl.mongodb.org/linux/mongodb ...

  7. BZOJ3512 DZY Loves Math IV(杜教筛+线性筛)

    注意到n很小,考虑枚举i.现在要求的是f(n,m)=Σφ(in) (i=1~m).显然当n没有平方因子时,φ(in)=φ(i)·φ(n/gcd(i,n))·gcd(i,n).利用φ*1=id又可得φ( ...

  8. aliyun阿里云alibabaMaven仓库地址——加速你的maven构建

    在maven的settings.xml 文件里 搜索  mirrors   ,把下面内容添加在其子节点内 <mirror> <id>nexus-aliyun</id> ...

  9. BZOJ4037:[HAOI2015]数字串拆分——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4037 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时 ...

  10. 遇到问题----linux-----linux 打开文件数 too many open files 解决方法

    在运行某些命令或者 tomcat等服务器持续运行 一段时间后可能遇到   too many open files. 出现这句提示的原因是程序打开的文件/socket连接数量超过系统设定值. 查看每个用 ...