快读快写和fread,fwrite--zhengjun

首先,先谈谈快读快写

这是我一开始的输入输出

cin>>a;
cout<<a;

然后,因为在一次模拟赛中 c i n cin cin被卡掉了,于是,我就改用

scanf("%d",&a);
printf("%d",a);

可是,又有一道题,我打出了正解,可是 T T T掉了一个点,结果用了快读快写,就 A A A了,为什么快读会这么快,因为读入输出字符比读入输出数字快许多

不过,快读还有可能被卡,比如说一个数据,有许多多余的空格,这样你就没办法了,只好改回 s c a n f scanf scanf。(不过我没有见过这么毒瘤的数据),当然快写也可以用递归式的,不过这样似乎会慢一点

inline void read(register int &x){
    x=0;register int f=1;register char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}//判断负数
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    //其中(x<<3)+(x<<1)等价于x*10,(c^48)等价于c-'0'
    x*=f;
}
inline void write(register int &x){ 
	register int len=0,k1=x;
	if(k1<0)k1=-k1,putchar('-');
	while(k1)c[len++]=k1%10+'0',k1/=10;
	while(le--)putchar(c[len]);
}

这样,就是一个快读快写了。

当然你也可以写成有返回值的形式,不过我觉得 v o i d void void会快一点,因为它少定义一个变量

inline int read(){
    register int x=0,f=1;register char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}//判断负数
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    //其中(x<<3)+(x<<1)等价于x*10,(c^48)等价于c-'0'
    return x*f;
}
inline void write(register int x){
	if(x>9)write(x/10);
	putchar(x%10+'0');
}

还有一点,快写是输不出 0 0 0的,因为我习惯用 p r i n t print print,所以,快写用 w r i t e write write,再用一个 d e f i n e define define

#define print(x) if(x==0)putchar('0');else write(x)

不知道为什么用三目表达式会编译错误。

然后,来说一说fread和fwrite

这个东西是个啥呢,就是文件读入输出的东西,如果不是文件读入的话 f r e a d fread fread是不能用的,而 f w r i t e fwrite fwrite是可以用的。

这个东西因为我们一次一次分开读入输出一个字符没有通过文件一次性读入输出一坨快,所以,就有了优化。

这两个东西在各种 O J OJ OJ上面还是适用的,因为 O J OJ OJ上就是文件读入输出的。

size_t fread( void *restrict buffer, size_t size, size_t count, FILE *restrict stream );

b u f f e r buffer buffer是读入的数据存放的字符串, s i z e size size是每一次读入的个数, c o u n t count count是读入的次数, s t r e a m stream stream是输入流

可是本来可以在 f r e a d fread fread里面每一次多读入几次,可是如果剩余的数据不够了,就无法读入成功,而 s t a t stat stat可以求出文件的长度这样就可以了,可是 w i n d o w s windows windows似乎不行,哎!!!

f r e a d fread fread的返回值是

如果读入成功(一定要读完,说要读多少个少一个都不行),返回1,否则返回0

size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

这个其实和 f r e a d fread fread的参数一样。只不过我们可以在输出的时候一次全部输出玩,也就是fwrite(buffer,1,buffer的len,stream);

然后,这两个东西就可以替代 g e t c h a r getchar getchar p u t c h a r putchar putchar,会快一点。

这里要用到指针,如果不会的请先学习指针,然后再来看。

static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)

注意 g e t c h a r ( ) getchar() getchar()里面的

(p2=(p1=buf)+fread(buf,1,1000000,stdin)

中的加号是指针。

最终的模板

#include<bits/stdc++.h>
using namespace std;
static char buf[1000000],*p1=buf,*p2=buf,obuf[1000000],*p3=obuf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
#define putchar(x) (p3-obuf<1000000)?(*p3++=x):(fwrite(obuf,p3-obuf,1,stdout),p3=obuf,*p3++=x)
template<typename item>
inline void read(register item &x){
    x=0;register int f=1;register char c=getchar();
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
    x*=f;
}
template<typename item>
inline void uread(register item &x){
    x=0;register char c=getchar();
    while(c<'0'||c>'9')c=getchar();
    while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
}
static char cc[20];
template<typename item>
inline void print(register item x){ 
	register int len=0;
	if(x<0)x=-x,putchar('-');
	while(x)cc[len++]=x%10+'0',x/=10;
	while(len--)putchar(cc[len]);
}
template<typename item>
inline void uprint(register item x){ 
	register int len=0;
	while(x)cc[len++]=x%10+'0',x/=10;
	while(len--)putchar(cc[len]);
}
int main(){
	
	fwrite(obuf,p3-obuf,1,stdout);
	return 0;
}

普通的输入输出:read(x),print(x),无符号的输入:uread()

支持同一文件中的intlong long的同时输入输出

例如:

int main(){
	int x;
	unsigned int ux;
	long long y;
	unsigned long long uy;
	read(x);uread(ux);
	read(y);uread(uy);
	print(x);putchar(' ');uprint(ux);
	putchar('\n');
	print(y);putchar(' ');uprint(uy);
	fwrite(obuf,p3-obuf,1,stdout);
	return 0;
}

输出A_zjzj

谢谢–zhengjun

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

A_zjzj

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值