读入和输出


最近在蓝桥杯发现一些奇怪的题,发现自己读入和输出都写不明白,于是来写一个读入和输出专题。

读入

读入主要的写法有:scanf,cin,getchar和快读

scanf

以下为scanf()函数的声明:

  int scanf(const char *format, ...)

格式符

format是一个c字符串,包含了以下各项中的一个或多个:空格字符、非空格字符 和 format 说明符。

比赛中常见的format说明符有:

格式符 功能
%d 读取十进制整数,有符号也会自动读入。
%c 读取单个字符。
%f 读入单精度浮点型。
%s 读入c库中的字符串(char[],不能读string)。
%lf 读入双精度浮点型

%相当于一个转义字符。

一些tips

scanf只会读取格式部分内容,后面的任何内容都不会被读取(包括回车空格)。

scanf在按固定格式读入的时候非常有用,在比赛中诸如日期,百分数的读入都可以用。

另外,题目中有时候会出现数据规模不提供的情况,而scanf是具有返回值的。这也就意味着,在输入个数未知时可以利用scanf的读入返回值进行判断是否完全读入。

scanf读入较快,能应对较多读入较大的场景。

*最新刷题结果显示,scanf甚至可以处理不同格式的问题。当scanf在后续仍有输入但格式不符时,scanf会立即停止读入并返回成功读取到的变量个数。后续仍可以用scanf读入后续变量。

cin

我觉得cin就是图个省事

cin好像有各种各样的用法,但我本人真的不喜欢用,我觉得cin的好处就是不用写格式符。

加速

cin虽然方便但是速度较慢,因此可以用如下代码进行加速:

  ios::sync_with_stdio(false);
  cout.tie(NULL);

使用这两行代码可以使得cin的速度比scanf还要快一点,代价是cin/cout不能和scanf/printf混用了

getline

cin可以很方便地获取一整行,我本人习惯写如下代码:

  string s;
  getline(cin,s);

一般的读入不能读入整行内容,但是这个可以。(当然c库中的gets也是很好用的)

getchar

getchar是c库中读取字符串的方法。这个函数非常简单和基础,只从缓冲区读取一个字符。但正是因为其基础,它才有较为广泛的应用空间和最快的速度。当不知道如何实现读入时,getchar是最后的办法(一般来说不会发生这种情况)

快读

全称快速读入,在数据范围到达一定大小后(貌似是1e6-7)会极大影响程序运行效率,甚至可能出现不用就TLE用了就AC的情况。(出现这种情况一般是因为方法本身不够优,但快读确实可以让一部分不够优的方法通过测试数据)

源代码网上一堆,但是最快的版本还是fread的而不是getchar的,如果需要还是直接去网上抄的比较好。

输出

输出主要方法就是printf,cout,其他好像用不上。

printf

朴实无华的好函数。

格式符

printf的常用格式符比scanf的多一些,因为要控制输出格式。

printf的格式控制的完整格式:
% -0 m.n l或h 格式字符
下面对组成格式说明的各项加以说明:

  1. %:表示格式说明的起始符号,不可缺少。
  2. 0:有0表示指定空位填0,如省略表示指定空位不填。(配合3输出时间类非常好用)
  3. m.n:m指域宽,即对应的输出项在输出设备上所占的字符数。N指精度。用于说明输出的实型数的小数位数。为指定n时,隐含的精度为n=6位。
  4. l或h:l对整型指long型,对实型指double型。h用于将整型的格式字符修正为short型。(不用h)

cout

cout和cin同理,也可以用上面的代码加速,也是图个方便,也是控制格式不是很方便,没啥讲究。