C++ IO的一些注意点
读入这个坑一直以来都深受其麻烦,把遇到一些注意点记一下吧。
1.getchar读入
以前练线段树的时候做到Acwing#246 Interval GCD(原题在CodeHunter上,人懒就在Acwing上交了),怎么调也调不过去,样例和手造的数据统统没有问题,当时甚至怀疑数据出问题了拿人家题解交了一发,发现过了然后特别自闭,后来整了好久才发现是读入的锅,实测的数据可能没有给的样例那样整齐有序,把
type=getchar();
改成
do type=getchar(); while(type!='C'&&type!='Q');
然后就过了2333。
调代码期间收获了4*Segmentation Fault,10*Wrong Answer,1*Time Limit Exceeded,现在看着都害怕。
getchar读入时一定要while判断一下读进了什么东西。
2.cin去同步
上次模拟赛读入图快,cin去同步+getchar()读字符串,然后我就错失了一次绝佳的AK的机会。。
本地里跑得可好了,结果成绩出来获得了爆零的好成绩,Linux上连样例都跑不过,赛后把去同步删掉结果就AC了。
去网上了解了一下,istream本身读入时是和cstdio共用一个缓冲区的,输入的数据先进入缓冲区,然后两者都从中读入数据,而当加入
ios::sync_with_stdio(false);
的时候,iostream不再和cstdio同步使用同一个缓冲区,cin读完以后剩下的\n\t和空格都留在istream的缓冲区里,当你再调用cstdio的读入函数时,cstdio的缓冲区内没有数据,这时就会出现错误。所以去同步以后千万不能把两个库的函数混用,当然,这时快读也不能用了。
当时模拟赛竟然还有数据返回Dangerous Syscalls,这冲突也是严重啊。
3.快读read()调用
这也是一个奇怪的坑,不过这种在调样例的时候一般是能发现的
如果直接将读入结果作为实参传到函数里,那实际函数得到的参数是和读入顺序相反的,不大清楚具体是什么原因,应该和c++内部函数的机制有关吧。
快读最好先将数据保存到变量再处理。