c語言筆記——對scanf()等輸入函數的深入理解

  輸入函數是我們可以說是接觸最早的一批函數了,但是如果不注意的話還是會遇到很多問題,所有我把平時遇到的一些問題和想法寫下來。肯定會有不對的地方歡迎大家指正。

scanf()

  • scanf()這個函數是從輸入緩衝區中讀取數據的而不是從鍵盤上讀取數據的

這些在上完學校的課之後應該都知道了,可是還是有很多的細節要注意。(原來我也知道可是在使用時還是犯錯了。

  • scanf()這個函數在輸入時遇到,空格,製表符,回車,和非法輸入時結束

注意是輸入結束而不是函數結束。

  • scanf()在所有數據域中均有數據且遇到回車時結束。
    -scanf()只有在是%c這個格式時纔會讀取空格和回車中的換行符

看到有的人在博客中寫到scanf()在讀取字符串時,會丟棄後面的換行符,然而在試驗中發現依然會出現‘跳過’的現象,所已覺得這個解釋更合理。

其他還有一些使用方法書上已經十分詳細的講解了,就不多贅述了。
下面通過一些實例說明上面的一些問題:
1.


#include<stdio.h>
int main()
{
    int a, b;
    scanf("%d", &a);
    scanf("%d", &b);
    printf("%d %d", a, b);
}

這個代碼在輸入的時候除了,一個一個的輸入之外,如果你一次輸入2 3並按下回車,你會發現第二個scanf()函數被‘跳過’了,直接顯示出2 3的結果了。這說明scanf()是從緩衝區直接讀取數據,而不是鍵盤,只有當輸入緩衝區沒有數據纔會要求從鍵盤輸入。
2.

#include<stdio.h>
int main()
{
    char a[10];
    scanf("%s", a);
    printf("%s", a);
}

這樣一段代碼如果你輸入‘hello world’你會發現輸出的只有hello,這是因爲它在讀取到空格的時候就停了,所已一般不用它來輸入字符串,雖然也可以通過scanf("%[^\n]",a)來實現輸入句子,但是還是用gets更好一點。(這是一個正則表達式的用法,意思是遇到\n才停下來,其實對於這個我也不是很清楚)
3.


#include<stdio.h>
int main()
{
    char a, b;
    scanf("%c", &a);
    scanf("%c", &b);
    printf("%d %d", a, b);
}

這段代碼的本意很簡單就是輸出輸入的兩個的字符在ASCII表中的值,但是實際結果是如果你會車後輸入b,會發現b的值一直是10,或像上面一樣用空格隔開輸入,那麼b就一直是32.這是因爲當爲%c時scanf()可以讀入空格和回車符。當輸入完a的值之後,scanf()讀走了一個值,而回車還留在輸入緩衝區了,第二個就直接讀取了,查表發現回車就對應10,空格就對應32,製表符當然也不例外了。如果是讀取字符串就不會出現這個問題了。

對了還有一個就是在使用scanf_s()這個函數的時候因爲安全原因,在輸入字符串的時候如果不寫緩衝區大小(也就是最大字符長度)運行的時候就會報錯,在變量後面加個長度就可以了。


  從臨近考試周到寒假都快過了大半了,在這段時間裏一直在玩耍實在是罪過啊。現在找時間把自己未完成的博文寫完,不知道自己還記得不。


getch()和getche()

  這兩個函數的功能非常的相似,都是直接從鍵盤讀取數據而不是從緩衝區,他們的區別是前者無回顯後者有回顯。在這裏回顯的意思就是回在屏幕上顯示出你輸入的東西,下面舉個簡單的例子就很容易明白了。

#include<stdio.h>
#include<conio.h>
int main()
{
    char a;
    a=getch();
    printf_s("%c", a);
}

這個程序如果你輸入的是‘a’那麼顯示的只有a,而如果把getch()換成getche()那麼結果就是‘aa’了。這說明getch()這個函數沒有回顯也就是不把輸入的內容顯示在顯示器上。

gets()

  這個函數的功能是從輸入緩衝區中讀取字符串,直到遇到換行或者是EOF才停止。這個函數一般用來輸入句子。但是和scnf()用來輸入字符串一樣存在安全問題。這個函數的原型是:

char *gets( char *buffer );

這個函數的形參只有一個指針,沒有限制輸入的數目,也就是說這個函數可以無限的輸入這樣很有可能就會造成溢出。所以現在用gets_s()來代替這個函數。

清空輸入緩衝區

  有的時候我們需要清空輸入緩衝區,然後重新輸入數據。常用的有fflush(stdin);這個函數。某些編譯器(如VC6)支持用 fflush(stdin) 來清空輸入緩衝,但是並非所有 編譯器都要支持這個功能(linux 下的 gcc 就不支持),因爲標準中根本沒有定 義 fflush(stdin)。
  而更加實用也更加經典的則是:

  char c;
while((c = getchar()) != '\n' && c != EOF);

由代碼知,不停地使用getchar()獲取緩衝區中字符,直到 獲取的字符c是換行符’\n’或者是文件結尾符EOF爲止。這個方法可以完美清除輸入緩衝區,並且具備可移植性。

  以上是我對於c語言的一些理解,如有不對的地方歡迎大家評論指正,也歡迎大家交流學習。這裏是我在github上的一個博客,感興趣的可以去看一下哦

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章