1.getline
getline是包含于头文件:<string>的函数
作用:读取一行字符串(包含空格)
使用格式:getline(cin,str);
cppstring a; getline(cin, a);
假设我们有一个场景是需要识别一行字符串中的字母a的个数,我们有两种读取策略
**策略1:**先用getline读取一整行的字符串,然后一个个字符进行判断
**策略2:**由于空格是否读取不会影响最终结果,所以我们直接用cin读取一个个单词,然后一个个字符判断。
这里就可以看出cin和getline的使用区别,cin会自动忽略掉空格读取,而getline会保留空格读取
2.fgets与fputs
这两个都是包含于头文件:<cstdio>的函数
fgets的作用是从文件中读取字符并存在str中
使用格式:
char * fgets ( char * str, int num, FILE * stream );
num表示读取的个数,str是指向存储读取到的字符串的char数组的指针,stream是文件流
fputs的作用是将str写入文件流中
使用格式:
int fputs ( const char * str, FILE * stream );
3.数字的特殊处理方式
其实在控制台中,当我们输入数字的时候编译器识别出来的是字符,只不过当我们把这个读取的数据给到整型变量或者其他数字类型的变量的时候,他会按照你给定的类型来解读这个字符数据。
然后在输出数据的时候其实也是按照字符输出的,编译器将变量中的数据转换成字符类型输出
下面我们解读一下例子:
这里我们从键盘输入的123,其实被编译器识别为字符'1''2''3',然后由于我们给到的是变量a,所以编译器会按照整型数据的方式来识别字符,于是最终就识别出了123给到a变量
下面我们用一道题来讲解我们可以如何利用编译器的这种特性来简单解题:
本题需要我们将数字的奇数对应位置改为1,偶数对应位置改为0。
方法一:数字处理
第一步:将数据录入
第二步:当当前数据%10的结果是奇数的时候,将当前ret+=乘上权重的1,然后/10将当前位数去掉,循环n次
第三步:输出结果
方法二:字符串处理
第一步:将数据以字符串的形式录入
第二步:利用for循环对字符串的每一位进行取余判断,若为偶数就将当前位置数据改为0,为奇数就改为1
第三步:将字符串通过stoi转为整数之后输出
注意:第三步之所以要转换为整数,是为了处理前导0的情况
经过这两种方法的对比:我们发现,将数据转换为字符串的处理方式是很简单的,而整数的处理方式相对麻烦。其实在算法竞赛中我们关注的仅仅是结果,过程是怎样的并不重要
4.printf/scanf和cin/cout的对比
在输入数据量不大的时候,由于cin和cout的自动识别数据类型的特性,我们一般使用cin和cout更多一点,但是有时候我们需要格式化输出数据,我们就不得不使用printf了。
(1)格式输出差异
cin和cout可以自动识别数据类型,避免出现格式错误,但是无法精确控制输出格式。
printf和scanf需要手动指定输入和输出格式,如果输入/输出格式对不上会出现不符合预期的问题,但是可以实现精确的定制化输出
(2)性能差异
结论:优化后的cin/cout > printf/scanf > 没优化的cin/cout
**没优化的cin/cout慢的原因:**由于他们需要负责兼容c语言printf/scanf的任务,所以他们在执行输入输出的时候会有一些多出的指令需要同步执行,从而导致他们没有printf/scanf快
两个具体原因:
(1)为了兼容c,c++在每次使用cout/cin的时候都会刷新c标准库的缓冲区,这意味着cout和cin每次都要将数据同步给printf和scanf,以确保他们的i/o流是一样的
(2)cin和cout之间有一层绑定关系,这个关系具体来说就是cin每次调用前会向cout发送一个指令,让cout将待输出的数据刷新到屏幕上,当输入输出数据量很大的时候,这个指令的总延时就很大了
那么我们有什么方式优化cin/cout?
cppios::sync_with_stdio(false); //取消给C语⾔输⼊输出缓冲区的同步 cin.tie(0); //取消了cin和cout的绑定
通过取消对c输入输出缓冲区的同步,以及取消cin/cout的绑定关系,我们可以显著提升cin/cout的效率
注意:
**1.取消同步带来的问题:**在多线程环境下会有安全问题,且不再支持c语言的输入输出,因为取消了数据对c输入输出流的同步
2.取消同步的使用场景:
算法竞赛中只使用c++的输入输出时/程序确保只使用c++的输入输出
3.取消绑定的使用场景:
算法竞赛中的高性能输入输出/非交互式程序(输出内容不用在用户输入一次数据之后直接输出)/并行处理数据时,可以减少因为cout还没输出而浪费的cin等待时间
总结:
输入输出数据量:小于1e6,都可以 ; 小于1e9,建议用printf和scanf ; 更大的时候需要用快速读写