权御天下快速io模板(OI(CSP?)专属限定版)

权御天下

2018-10-01 23:04:22

Personal

## 呀吼~全新的读写模板出炉啦~ 注:由于本帖是为了向不怎么会写io优化的萌新介绍io优化的特性,故个别地方可能讲的对于dalao而言比较啰嗦 --- ## 2019.10.10更新 * 加入了字符串型输出的功能 * (等待)加入字符串型读入功能(尽量在复赛前填完这个坑QAQ) --- 以下为原贴内容 比较于[上一个版本的读写模板](https://www.luogu.org/paste/eo9guj94),本次模板做了如下改进: --- ### update:1、取消了浮点数读入功能 因为OI竞赛中不太常出现带有浮点数的题,而且手写浮点读入很慢很慢...而且精度不怎么样 重点还是**很慢很慢**... --- ### update:2、整形读入更改为取址式赋值 这个基本上就是个人兴趣了 ~~虽然理论上还能节省一个赋值的时间~~ --- ### update:3、支持自定义输出数字后的分隔符 也许会有人注意到这份模板的print函数比一般多了一个参数 ```cpp inline void print(Type x, char text = '\n') --------^------- ``` 这是蒟蒻加的一个小功能,用于设置输出数字后使用的分割符,对应函数中的 ```cpp while (fr) *oS++ = fu[fr--]; *oS++ = text; ------^------ out(); ``` 这个参数是有一个默认值(换行)的,所以一般情况下不需要增加第二个参数,比如主程序中 ```cpp print(number); ``` 这个指令,就会输出一个数字number,并在数字结尾加上一个换行符('\n) 而在部分题目中,数字间不是要求用换行符分隔而是空格,有了这个就很好办了 怎么弄呢?很简单 ```cpp print(number, ' '); ``` 我们将第二个参数手动设置为空格(' '),而不是默认的换行符,就可以做到输出number并在结尾加上一个空格了 同时,对于一些题目,大部分数字被要求以空格分隔,而一个个打参数又很费劲 当然是修改默认值比较省事了啊 ```cpp inline void print(Type x, char text = ' ') ``` 把函数参数的默认值改成空格,print的用法就变成了 ```cpp print(number); ``` 和 ```cpp print(number, '\n'); ``` 意义同上 --- ### update:4、在print()函数尾自动flush并写入文件 同样是个人兴趣 ~~我是不会告诉你们我经常print写入缓存之后忘记fwrite的~~ --- ### update:5、代码更加精简(?),更适合考场使用 相比于上一个版本的模板,这次的删改之后短了许多的好不好 ~~2019.10.10 update:加了各种实用(毒瘤)功能之后模板再一次变得巨大了QAQ~~ 不管到底精简了多少,至少这个在考场上写出来的难度要低多了 ~~那些在一个struct里就能搞出一套io的dalao们就当我没说过这句话~~ --- ### update:6、逻辑性更强,更利于记忆 个人认为这次写的逻辑性不错的(为了逻辑性特意把之前的S和T拆成了iS,iT,oS,oT),相信写过普通快读的同学对fread和fwrite的用法稍加理解之后就能轻易的读懂这份模板 ~~然后自己去研发出了更加强大的模板并把本蒟蒻的模板弃置不管了~~ --- ### update:7、关于putc()函数 有些dalao看完代码问我putc函数去哪了?当然是没有了啊~ 总体上感觉,有了可定义结尾是换行还是空格的print之后,应用本就不多的putc更是没什么用了,加之putc好写到无法形容,就没加在这里 如果萌新没写过fread的话,那我就在这里给出一份好了(一般加在io::out()函数的下面) ```cpp inline void putc(char x) { *oS++ = x; out(); } ``` 没了? 没了。 ## update:8、关于新加入的字符串输出 核心代码如下 ``` inline void prints(char x[], char text = '\n') { for (register int i = 0; x[i]; ++i) //判断是否读到头 * oS++ = x[i]; //写入缓存 * oS++ = text; //输出结尾 out(); //愉悦的fulsh() } ``` 需要额外注意的是,当你使用这个函数的时候,~~因为咱代码写的丑所以~~ 需要**确保你的char数组末尾是一个空值**(即char 0) > 关于char型参数text,请参照update:3中的介绍 --- ### 本模板食用方法: ~~直接去掉头就可以吃了~~ **以下为模板中功能函数(即平时直接使用的函数)的食用方法** > 1、read()函数 (仅限数字读入) 使用方法为直接将你要赋值的变量写入函数参数内,形如`read(n)` **支持自动识别int,uint,LL,uLL** ~~字符读入请等待咱的下一次更新~~ > 2、print()函数 (仅限数字输出) 使用方法为将你要输出的变量写入函数参数内,形如`print(n)`或`print(n, ' ')`等 *关于第二个参数请参照update:3中的介绍* **同样支持自动识别int,uint,LL,uLL** > 3、prints()函数 (仅限字符串输出) 假设你的char数组是以0下标为起始位(即`char[] = { 'a', 'b', 'c', 'd', ... }`,你可以直接引用函数`prints()`,形如`prints(a)` 假设你的char数组不是以0下标为起始位(即`char[] = { 0, 0, ..., 'a', 'b', 'c', 'd', ... }`)你需要对引用的数组地址进行调整,方法为将你的取址后移&n&位(&n&为你的char数组起始位下标),形如`prints(a + 1)` ~~支持自...emmmm...自动识别char和char~~ ~~**识别string是不可能的,这辈子都不可能**~~ #### ~~单个字符输出建议使用putchar()函数~~ --- 该说的基本上都说了,下面放上完整的io模板 ## 权御天下快速io模板(2018(9?)OI(CSP?)专属限定版): ```cpp namespace io { #define gc() (iS == iT ? (iT = (iS = ibuff) + fread(ibuff, 1, SIZ, stdin), (iS == iT ? EOF : *iS++)) : *iS++) const int SIZ = 1 << 21 | 1; char* iS, * iT, ibuff[SIZ], obuff[SIZ], * oS = obuff, * oT = oS + SIZ - 1, fu[110], c; int fr; inline void out() { fwrite(obuff, 1, oS - obuff, stdout); oS = obuff; } template<class Type> inline void read(Type& x) { x = 0; Type y = 1; for (c = gc(); (c > '9' || c < '0') && c != '-'; c = gc()); c == '-' ? y = -1 : x = (c & 15); for (c = gc(); c >= '0' && c <= '9'; c = gc()) x = x * 10 + (c & 15); x *= y; } template<class Type> inline void print(Type x, char text = '\n') { if (x < 0) * oS++ = '-', x *= -1; if (x == 0) * oS++ = '0'; while (x) fu[++fr] = x % 10 + '0', x /= 10; while (fr) * oS++ = fu[fr--]; * oS++ = text; out(); } inline void prints(char x[], char text = '\n') { for (register int i = 0; x[i]; ++i) * oS++ = x[i]; * oS++ = text; out(); } } using namespace io; ``` 嗯...就这么多 如果哪位dalao觉得蒟蒻的模板有可以改进的地方欢迎私信或评论 如果哪位刚学io优化的同学不懂了也欢迎私信或评论区提问 ## 权御天下祝各位OIer rp++