适用于C++11以上的快速IO

注意事项

仅适用于C++11及以上,否则如果你得到CE后果自负。

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//#define FIO //开启加速模式 将不能使用键盘读入
struct IO {
#ifdef FIO
const static int BUFSIZE = 1 << 20;
char buf[BUFSIZE], obuf[BUFSIZE], *p1, *p2, *pp;
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,BUFSIZE,stdin),p1==p2)?EOF:*p1++)
#define pc(x) ((pp-obuf==BUFSIZE&&(fwrite(obuf, 1, BUFSIZE, stdout), pp = obuf)),*pp = x, pp++)
inline void flush() {
fwrite(obuf, 1, pp - obuf, stdout);
}
IO() {
p1 = buf, p2 = buf, pp = obuf;
}
~IO() {
fwrite(obuf, 1, pp - obuf, stdout);
}
#else
#define gc getchar
#define pc putchar
inline void flush() {};
#endif
template<typename Tp = int>
inline Tp read() {
Tp s = 0;
int f = 1;
char ch = gc();

while (!isdigit(ch))
f = (ch == '-' ? -1 : 1), ch = gc();

while (isdigit(ch))
s = s * 10 + (ch ^ 48), ch = gc();

return s * f;
}
template<typename Tp>
void read(Tp &x) {
x = read();
}
template<typename Tp, typename... Ts>
void read(Tp &x, Ts &...val) {
x = read<Tp>();
read(val...);
}
template<typename Tp>
void write(Tp x) {
if (x < 0)
pc('-'), x = -x;

static char sta[20];
int top = 0;

do
sta[top++] = x % 10 + '0', x /= 10;

while (x);

while (top)
pc(sta[--top]);
}
template<typename Tp, typename... Ts>
void write(Tp x, Ts... val) {
write(x);
pc(' ');
write(val...);
}
template<typename... Ts>
void writeln(Ts... val) {
write(val...);
pc('\n');
}
} io;

速度

这个模板是非常快的:

LOJ #7 / 读入3e6个long long / 五组数据开启-Ofast优化不开启优化
调试模式getchar433ms796ms
加速模式fread 无法使用键盘输入250ms539ms

用法

本模板实现了任何整数类型的读入/输出,同时可以自己写输出函数并使用高速IO。

读入

返回值模式

int x = io.read(); 读入一个int类型整数 xx

long long x = io.read<long long>(); 读入一个long long类型整数 xx (其他数据类型如__int128_tunsigned以此类推 不指定模板参数默认为int)

传参模式

1
2
3
4
5
6
7
8
int x;
io.read(x);//读入一个int类型整数x

__int128_t a;
int b;
unsigned long long c;
short d;
io.read(a,b,c,d);//如果使用传参方式可以自动推断类型并可以一次读入任意多个整数

输出

1
2
3
4
5
6
int x=1926,y=8,z=17;
long long a=1145141919810;
io.write(x,y,z);//与带参数的io.read()类似,如果一次输出多个数会自动加上空格,同样可以自动推断类型

io.writeln(x,y);//相当于使用io.write()后手动输出一个换行符

自定义读入/输出

模板定义了pc,gc两个宏(因为他们是宏所以不需要加io.前缀),用它们代替putchargetchar,开启快速模式后putchargetchar会失效。

自定义读入/读出函数必须要放在IO结构体内。

下面这个示例函数可以输出一个string

1
2
3
4
5
6
7
8
9
10
struct IO{

...//省略60行

void writeString(string str){
for(char ch:str) pc(ch);//注意不是io.pc
}
} io;

io.writeString("I AK IOI");//调用时要加io.

手动刷新输出缓冲区

如果你不知道这是什么意思可以跳过这段内容。

一般情况下,模板会在你的程序退出时自动刷新输出缓冲区并输出其中的全部内容。

如果你想在程序运行中手动刷新缓冲区(比如IO交互题)可以使用io.flush()

该函数在调试模式下是一个空函数(因为getcharputchar都是即时操作的)。


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!