权御天下快速io模板(OI(CSP?)专属限定版)
权御天下
2018-10-01 23:04:22
## 呀吼~全新的读写模板出炉啦~
注:由于本帖是为了向不怎么会写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++