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++內部函式的機制有關吧。
快讀最好先將資料儲存到變數再處理。