日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入了解scanf() getchar()和gets()等函数之间的区别

發(fā)布時間:2023/12/9 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入了解scanf() getchar()和gets()等函数之间的区别 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
----------------------------------------------------
| 問題描述一:(分析scanf()和getchar()讀取字符)?? |

--------------------------------------------------

scanf(), getchar()等都是標準輸入函數,一般人都會覺得這幾個函數非常簡單,沒什么特殊的。但是有時候卻就是因為使用這些函數除了問題,卻找不出其中的原因。下面先看一個很簡單的程序:

程序1:

[cpp]?view plaincopy
  • int?main()??
  • {??
  • ???????char?ch1,?ch2;??
  • ???????scanf("%c",?&ch1);???
  • ???????scanf("%c",?&ch2);??
  • ???????printf("%d??%d\n",?ch1,?ch2);??
  • ???????return?0;??
  • }??
  • 程序2:

    [cpp]?view plaincopy
  • int?main()??
  • {??
  • ???????char?ch1,?ch2;??
  • ???????ch1?=?getchar();??
  • ???????ch2?=?getchar();??
  • ???????printf("%d??%d\n",?ch1,?ch2);??
  • ???????return?0;??
  • }??

  • ? ?程序的本意很簡單,就是從鍵盤讀入兩個字符,然后打印出這兩個字符的ASCII碼值。可是執(zhí)行程序后會發(fā)現除了問題:當從鍵盤輸入一個字符后,就打印出了 結果,根本就沒有輸入第二個字符程序就結束了。例如用戶輸入字符'a', 打印結果是97,10。這是為什么呢?

    【分析】:
    ??? 首先我們呢看一下輸入操作的原理, 程序的輸入都建有一個緩沖區(qū),即輸入緩沖區(qū)。一次輸入過程是這樣的,當一次鍵盤輸入結束時會將輸入的數據存入輸入緩沖區(qū),而cin函數直接從輸入緩沖區(qū)中 取數據。正因為cin函數是直接從緩沖區(qū)取數據的,所以有時候當緩沖區(qū)中有殘留數據時,cin函數會直接取得這些殘留數據而不會請求鍵盤輸入,這就是例子 中為什么會出現輸入語句失效的原因!
    ??? 其實這里的10恰好是回車符!這是因為scanf()和getchar()函數是從輸入流緩沖區(qū)中讀取值的,而并非從鍵盤(也就是終端)緩沖區(qū)讀取。而讀 取時遇到回車(\n)而結束的,這個\n會一起讀入輸入流緩沖區(qū)的,所以第一次接受輸入時取走字符后會留下字符\n,這樣第二次的讀入函數直接從緩沖區(qū)中 把\n取走了,顯然讀取成功了,所以不會再從終端讀取!這就是為什么這個程序只執(zhí)行了一次輸入操作就結束的原因!


    ----------------------------------------------------
    |? 問題描述二:(分析scanf()和gets()讀取字符串)?? |
    ----------------------------------------------------

    首先我們看一下scanf()讀取字符串的問題:
    程序3:

    [cpp]?view plaincopy
  • int?main()??
  • {??
  • ???????char?str1[20],?str2[20];??
  • ???????scanf("%s",str1);???
  • ???????printf("%s\n",str1);??????
  • ???????scanf("%s",str2);????
  • ???????printf("%s\n",str2);????
  • ???????return?0;??
  • }??

  • ?程序的功能是讀入一個字符串輸出,在讀入一個字符串輸出。可我們會發(fā)現輸入的字符串中不能出現空格,例如:
    測試一輸入:
    Hello world!
    輸出:
    Hello
    world!
    【分 析】到此程序執(zhí)行完畢,不會執(zhí)行第二次的讀取操作!這個問題的原因跟問題一類似,第一次輸入Hello world!后,字符串Hello world!都會被讀到輸入緩沖區(qū)中,而scanf()函數取數據是遇到回車、空格、TAB就會停止,也就是第一個scanf()會取出"Hello", 而"world!"還在緩沖區(qū)中,這樣第二個scanf會直接取出這些數據,而不會等待從終端輸入。

    測試二:
    Hello[Enter]?
    Hello[輸出]
    world[Enter]
    world[輸出]
    【分析】程序執(zhí)行了兩次從鍵盤讀入字符串,說明第一次輸入結束時的回車符被丟棄!即:scanf()讀取字符串會舍棄最后的回車符!


    我們再看一下gets()讀取字符串的情況:
    用scanf來讀取一個字符串時,字符串中是不可以出現空格的,一旦出現空格,后面的數據就會舍棄殘留在緩沖區(qū)中。其實有另外一個函數是可以接受空格的,那就是gets(),下面我們看一下這個函數的應用,我們把程序3改動一下:

    [cpp]?view plaincopy
  • int?main()??
  • {??
  • ???????char?str1[20],?str2[20];??
  • ???????gets(str1);???
  • ???????printf("%s\n",str1);??????
  • ???????gets(str2);????
  • ???????printf("%s\n",str2);????
  • ???????return?0;??
  • }??

  • 【分析】顯然與上一個程序的執(zhí)行情況不同,這次程序執(zhí)行了兩次從鍵盤的讀入,而且第一個字符串取了Hello world! 接受了空格符,而沒有像上一個程序那樣分成了兩個字符串!所以如果要讀入一個帶空格符的字符串時因該用gets(), 而不宜用scanf()!


    --------------------------------------------------------
    | 問題描述三:(getchar()暫停程序,查看程序執(zhí)行結果)|
    --------------------------------------------------------
    ??? 不知道大家有沒有遇到過這樣的問題,有的編譯器程序執(zhí)行完后的結果界面不會停下而是一閃就沒了,以至于看不到執(zhí)行結果。所以很多人在程序最后加上 getchar()語句,目的是想讓程序執(zhí)行完后停下來,等待從終端接收一個字符再結束程序。可是發(fā)現有時候這樣根本沒用,程序照樣跳出去了。這是為什么 呢?
    【分析】原因跟上面例子講的一樣,是因為輸入緩沖區(qū)中還有數據,所以getchar()會成果讀到數據,所以就跳出了!

    ------------------
    | ? 【總結】 ? |
    ------------------

    第一:要注意不同的函數是否接受空格符、是否舍棄最后的回車符的問題!
    讀取字符時:
    scanf()以Space、Enter、Tab結束一次輸入,不會舍棄最后的回車符(即回車符會殘留在緩沖區(qū)中);
    getchar()以Enter結束輸入,也不會舍棄最后的回車符;
    讀取字符串時:
    scanf()以Space、Enter、Tab結束一次輸入
    gets()以Enter結束輸入(空格不結束),接受空格,會舍棄最后的回車符!

    第二:為了避免出現上述問題,必須要清空緩沖區(qū)的殘留數據,可以用以下的方法解決:
    方法1:C語言里提供了函數清空緩沖區(qū),只要在讀數據之前先清空緩沖區(qū)就沒問題了!
    ?????? 這個函數是fflush(stdin)。
    方法2:自己取出緩沖區(qū)里的殘留數據。
    (說實話這個語句我也沒看懂,呵呵!為什么格式控制是這樣的!希望高手指點一下!)
    ?????? scanf("%[^\n]",string);

    總結

    以上是生活随笔為你收集整理的深入了解scanf() getchar()和gets()等函数之间的区别的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。