[筆記]scanf的使用(主要是針對char)


學的是C++,用cin cout也用的很順溜,寫自己的類時重載“<<”與“>>”運算符也很爽,但是發現在刷算法競賽題時,cin cout很沒優勢,輸入量大時一道題我用cin cout要50ms,用scanf printf只要10ms、20ms,這個就差的太大了時間都花在輸入輸出上也是很郁悶。於是開始使用C的輸入輸出標准。輸出很正常,也可以輕松更改double輸出的精度,c++還要個iomanip頭文件,還煩一點。格式化字符%u %d %ld %lld %f %lf %s %c等就這幾個限死了,也就是只能輸入輸出這幾個系統自帶的格式,是沒法將自己的類重載到里面的,,只能自己做個print函數。不過畢竟面向對象是c++的內容。
就是那個輸入scanf有些異類。首先輸入得取地址,輸入int的a要&a不能寫a。這我總是忘記。先輸入整形、long long、double、字符串什么的都沒問題,可以任意換行。scanf(“%d%d%d%d”, &a, &b, &c, &d);
像下面這樣輸入
//123 2
//
//
// 23
//6
有任意空格和回車都可以接收。
而對於字符串char sss[100],不支持空格的讀取,要讀取空格得用gets()。
而scanf(“%s”,sss)還是scanf(“%s”,&sss)都可以,論壇里上說前者還少取個地址更快一點。
而對於char型,char ch;scanf(“%c”,ch);可以是可以,但是不能像int等一樣隨心所欲地加空格和回車,明明說好的scanf自帶無視回車和空格。比如下一段代碼

int main()
{
    int a, b, c, d;
    char x, y, z,s1[10],s2[10],s3[10];
    scanf("%d%d%d%d", &a, &b, &c, &d);
    scanf("%s%s%s", s1, s2, s3);
    scanf("%c%c%c", &x, &y, &z);
    printf("%c%c%c", x, y, z);
    printf("%d%d%d%d\n'%c'\t'%c'\t'%c'\n%s\n%s\n%s", a, b, c, d, x, y, z,s1,s2,s3);
    return 0;
}

輸入:
111 222 333 444 555 666 777 8 9 0
輸出:
111222333444
’ ’ ‘8’ ’ ’
555
666
777請按任意鍵繼續…

而輸入:
111
222
333
444
555
666
777
890
則輸出:
111222333444

’ ‘8’ ‘9’
555
666
777請按任意鍵繼續…

char的什么回車啊空格啊都讀進去了。
而如果先讀入char,一旦char壞掉了,后面也全亂了。

我總結的規律是:

scanf讀取int等內容時,讀取完一個數據后后面的空格回車僅僅是表示這個數據輸入完了,沒有略過,它一直存在於輸入緩沖區,而到了下一個數據,若也是int或字符串什么的,會自動把空格回車略過,直到找到應輸入的內容,然后讀取。而char不同,它不忽略本該讀取的數據前面的空白,就把那空格或回車讀進去了,如果是有多個空格回車,剩下那些空白就依然還存在與緩沖區,給下一個char讀取了。

我現在找到了以下幾種解決方案

  1. 使用fflush(stdin)。scanf讀取char之前,用fflush(stdin)空輸入緩沖區,使其為空,然后輸入char就不會有空白符阻礙了。
  2. scanf讀取char之前使用getchar()把’\n’和’ ‘吃了,getchar()不跳過空格回車。當然getchar()幾次,即吃幾個字符也是個問題,所以本方法僅適用於比如競賽題什么的,輸入格式都很標准,不會出現不定多少的空格回車。不過現在想想好像scanf和getchar功能一樣欸,都不跳空白的。那么這么說來直接用scanf吸收空格應該也是可以的,比如scanf(“%c%c”,&ch,&ch)但是好像沒見人用過。
  3. VJ上看到這個寫法scanf(“\n%c”,ch),即在每個輸入char的scanf里的%c前面,都加上\n。對於在scanf里不僅僅寫%c還寫其他的東西,就像輸出一樣,我沒細研究,就知道比如scanf(“233%c666”,ch)我必須先輸入233再輸入char再輸入666,想想好像也有道理,以此來忽略\n,但是我發現它也可以忽略空格。雖然不是很懂,空格和回車在編譯器眼里一樣嗎?於是試了試scanf(” %c”,ch),也一樣的效果!於是這就達到了與輸入int、double一樣的格式,任意輸入多少空格和回車都沒事了。現在也是這么在用,雖然其實我不是很懂其原理。
  4. CSDN論壇里看到有12級的大神說不要用scanf輸入字符。。不是很懂,全用getchar()嗎。。。還是輸入字符轉用cin。。。 0.0 [震驚哭]。

附[方法三]實例:

int main()
{
    int a, b, c, d;
    char x, y, z,s1[10],s2[10],s3[10];
    scanf("%d%d%d%d", &a, &b, &c, &d);
    scanf("%s%s%s", s1, s2, s3);
    scanf(" %c\n%c %c", &x, &y, &z);
    //x = getchar(), y = getchar(), z = getchar();
    printf("%d%d%d%d\n'%c'\t'%c'\t'%c'\n%s\n%s\n%s", a, b, c, d, x, y, z,s1,s2,s3);
    return 0;
}

輸入:(‘-’代表空格,為了方便觀察,而且CSDN這個編輯器對多個空格強行忽略成一個,其實完全沒必要合並多個空格和回車。好心辦壞事)
1—2–3—
4—5–
–6–
—–7–
—-8–
-9–
——-0–
輸出:
1234
‘8’ ‘9’ ‘0’
5
6
7請按任意鍵繼續…


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM