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. 新手向:Vue 2.0 的建议学习顺序

    新手向:Vue 2.0 的建议学习顺序 尤雨溪   1 年前 注:2.0 已经有中文文档 .如果对自己英文有信心,也可以直接阅读英文文档.此指南仅供参考,请根据自身实际情况灵活调整.欢迎转载,请注明出 ...

  2. PHP导出sql文件

    发现自己之前写的php导出sql数据为Excel文件在导出一些数据的时候出现了精度的问题,比如导出身份证号的时候会把后面变成0000.暂时先把这个问题留下,有空去看看到底是什么问题. 写了一个导出sq ...

  3. 熟悉常用Linux操作

    cd命令:切换目录 (1)切换到目录 /usr/local cd /usr/local (2)去到目前的上层目录 cd .. (3)回到自己的主文件夹 cd ~ ls命令:查看文件与目录 (4)查看目 ...

  4. 再谈 最速下降法/梯度法/Steepest Descent

    转载请注明出处:http://www.codelast.com/ 最速下降法(又称梯度法,或Steepest Descent),是无约束最优化领域中最简单的算法,单独就这种算法来看,属于早就“过时”了 ...

  5. java中new两个对象,在堆中开辟几个对象空间

    内存堆中有两个对象,两个对象里都有独立的变量.p1 p2指向的不是同一个内存空间. 也可以这样描述引用p1,p2指向两个不同的对象.

  6. java递归方法求数组最大元素

    一直对递归写法不是很熟悉,特写一个增进理解 /** * Created by Administrator on 2017-11-01. */ public class recursion { priv ...

  7. Python画统计图

    https://blog.csdn.net/jenyzhang/article/details/52046372

  8. HNOI2013旅行

    一道欺负我智商的题... 本来想打单调队列优化dp的,结果看到算法标签就点了此题 洛谷题面 首先你要理解题意,蒟蒻理解了好久.它就是说,给你一个由1和-1组成的数列,让你分成m段,并让这m段区间和最大 ...

  9. 使用mshta.exe绕过应用程序白名单(多种方法)

      0x00 简介 很长一段时间以来,HTA文件一直被web攻击或在野恶意软件下载程序用作恶意程序的一部分.HTA文件在网络安全领域内广为人知,从红队和蓝队的角度来看,它是绕过应用程序白名单有价值的“ ...

  10. 20165218 《网络对抗技术》Exp2 后门原理与实践

    Exp2 后门原理与实践 准备工作 1. 查看Linux和Win的IP地址,ping通 Linux地址 Win7地址 ping 2.下载ncat并装载到win7主机 3.下载socat并装载到win7 ...