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. beta发布简评

    第一组:新蜂小组 题目:俄罗斯方块 评论:主体功能已经完成,可以流畅的进行游戏,无论效果或是功能都实现的很好. 第二组:Nice团队 题目:约跑APP(约吧) 评论:作为应用,想法创意很好:功能实现上 ...

  2. Teamcity部署.net服务“无法连接到远程服务器”解决方式

    在公司Teamcity上执行自动部署.net服务的时候,发现Teamcity在启动default.aspx的时候报错了,提示:使用“0”个参数调用“GetResponse”时发生异常:“无法连接到远程 ...

  3. Linux上两种网络连接方式

    模式一:NAT方式好处:路由器更换,或者交换机更换,网络仍然可以使用,所用使用最多 准备工作: 查看VMware服务器启动情况,五个全开模式 vmnet8开启模式 1 配置VMware交换机的ip地址 ...

  4. requests爬取知乎话题和子话题

    zhihu.py # *_*coding:utf-8 *_* import pymysql import requests from lxml import etree from requests_t ...

  5. yii 验证码 CCaptcha的总结(转)

    今天用到yii的验证码 ccaptcha,经过在网上搜寻 找到以下例子: 1.在controller中加入代码 (1)启用 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 &l ...

  6. Html5 web 本地存储 (localStorage、sessionStorage)

    HTML5 提供了两种在客户端存储数据的新方法localStorage,sessionStorage sessionStorage(临时存储) :为每一个数据源维持一个存储区域,在浏览器打开期间存在, ...

  7. java 构造器二

  8. c++11 智能指针 unique_ptr、shared_ptr与weak_ptr

    c++11 智能指针 unique_ptr.shared_ptr与weak_ptr C++11中有unique_ptr.shared_ptr与weak_ptr等智能指针(smart pointer), ...

  9. 【BZOJ3622】已经没有什么好害怕的了(动态规划,容斥)

    [BZOJ3622]已经没有什么好害怕的了(动态规划,容斥) 题面 BZOJ 题解 很明显的,这类问题是要从至少变成恰好的过程,直接容斥即可. 首先我们要求的是(糖果>药片)=(药片>糖果 ...

  10. Windows Shell远程执行代码漏洞((CVE-2018-8414)复现

    0x00   SettingContent-ms文件介绍 .SettingContent-ms是在Windows 10中引入的一种文件类型,它的内容是XML格式进行编写的,主要用于创建Windows设 ...