国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

C語言中scanf()函數(shù)對程序健壯性不良影響的解決辦法

2016-06-14 00:00韓平
電腦知識與技術 2016年12期

韓平

摘要:C語言中格式輸入函數(shù)scanf() 的格式控制字符串中除格式說明符以外的其他字符都必須由用戶從鍵盤原樣輸入,否則,就會出現(xiàn)意想到的結果或程序運行意外中止。C語言中的gets(char s[])函數(shù)接受鍵盤輸入或已經(jīng)存在于輸入緩沖區(qū)中的所有字符,包括回車符,但回車符不寫入字符串s中,而是在遇到回車符時,為s添加字符串結束標志符\0。該文通過實例,利用do-while循環(huán),結合gets()函數(shù),給出了一個解決格式輸入函數(shù)scanf()對程序健壯性不良影響問題的辦法。

關鍵詞:程序健壯性;輸入緩沖區(qū);scanf();gets();fflush(stdin)

中圖分類號:TP311 文獻標識碼:A 文章編號:1009-3044(2016)12-0107-02

Abstracts: All the format-control strings in scanf() of C language must be inputted into computer as they are by user from keyboard ,except for format specifiers. Otherwise, it can lead to some unexpected results or the program terminates unexpectedly. The function, gets (char s[]) of C Language, accepts keyboard input or all the characters in the input buffer, including carriage returns. Carriage return isnt written in s, and system adds the end symbol ‘\0 of string when encountering a carriage return. This paper gives a solution to the unwelcome effects on the robustness of program caused by scanf () of C language through do-while loop structure and gets(char s[]) function used in some examples .

Key words: the robustness of program; input buffer; scanf(); gets();fflush(stdin)

1 C語言中的scanf()函數(shù)對程序的健壯性會產(chǎn)生不良影響

C語言的輸入輸出都是通過函數(shù)來實現(xiàn)的,其中最常用的就是格式輸入函數(shù)scanf()。但這個函數(shù)的不良使用會給程序的健壯性帶來不好的影響。例如,程序pro1.c(設定銀行定期存款的年利率為2.25%,已知存款期為n年,存款本金為captial元,編程計算并輸出n年后的本利之和deposit[1])沒有考慮到用戶可能誤輸入非法字符的情況,其健壯性顯然不夠好。

2 scanf()函數(shù)對程序健壯性不良影響分析

函數(shù)scanf() 的格式控制字符串中除格式說明符以外的其他字符都必須由用戶從鍵盤原樣輸入[1]。如果用戶在輸入數(shù)據(jù)時沒有對格式說明符以外的其他字符原樣輸入,就會出現(xiàn)意想不到的結果或程序運行意外中止。因此我們在使用scanf()函數(shù)時先做到如下三點:一、調用一次scanf()函數(shù)只輸入一個數(shù)據(jù);二、scanf()函數(shù)中不出現(xiàn)格式說明符以外的字符;三、每次輸入數(shù)據(jù)前都先輸出一條提示信息給用戶。即便這樣,用戶仍然可能會誤輸入非法字符。Scanf()遇到空格符、回車符、制表符和非法字符都會認為數(shù)據(jù)輸入結束。對于程序pro1.c,如果程序運行到第一條scanf()函數(shù)調用語句時,用戶輸入“500abc”,由于輸入的字符“a” 、“b”、“c”非法,所以系統(tǒng)認為數(shù)據(jù)輸入結束。變量capital可以得到值500.0,“abc”還在輸入緩沖區(qū)中。程序運行到第二個scanf()函數(shù)調用語句時,系統(tǒng)不再等待用戶從鍵盤輸入數(shù)據(jù),而是直接從輸入緩沖區(qū)中取數(shù)據(jù)給變量n。由于字符“a” 、“b”、“c”都不是數(shù)字字符而是非法字符,所以scanf()函數(shù)調用失敗,也就為變量n取值失敗,但“abc”仍然在輸入緩沖區(qū)中。這時程序算是意外結束,得到的運行結果也會讓初學者感到迷茫。如果程序運行到第一個scanf()函數(shù)調用語句時用戶輸入數(shù)據(jù)合法,在程序運行到第二個scanf()函數(shù)調用語句時,用戶輸入“2abc”或“2.3”,因為n為int型,所以“abc”和“.3”為非法字符,系統(tǒng)認為數(shù)據(jù)輸入結束。變量n可以得到合法的值2,“abc”或“.3”仍在輸入緩沖區(qū)中。此時程序運行雖然正常結束,但這個結果同樣會令初學者感到迷茫。在此,給出防止用戶輸入非法字符而影響程序健壯性的辦法。除了格式說明符%s外,此方法對其它格式說明符都有效。

3 scanf()函數(shù)對程序健壯性不良影響的解決辦法

3.1利用gets()函數(shù)解決scanf()函數(shù)對程序健壯性不良影響的問題

gets(char s[])函數(shù)是C語言中的一個常用字符串輸入函數(shù)。它接受鍵盤輸入或已經(jīng)存在于輸入緩沖區(qū)中的所有字符,包括回車符,但回車符不寫入字符串s中,而是在遇到回車符時,為s添加字符串結束標志符\0。因此可以通過do——while循環(huán),結合gets()函數(shù)來解決上文中所提到的問題。在每個scanf()函數(shù)調用語句后都跟一條gets(s)函數(shù)調用語句,這樣就可以把所有非法數(shù)據(jù)放入s中,同時也就清空了輸入緩沖區(qū);把這兩條庫函數(shù)調用語句放入do——while循環(huán)中,只要用戶輸入非法數(shù)據(jù),字符串s的長度就會大于0,用戶就必須重新輸入數(shù)據(jù),直到某次輸入的數(shù)據(jù)完全合法為止(這時字符串s為空串,其長度為0)。

需要注意的是,字符數(shù)組s的長度一定要足夠長,否則程序運行也會意外中止。

3. 2輸入緩沖區(qū)的清空

關于上文提到的清空輸入緩沖區(qū)的問題,fflush(stdin)函數(shù)也是可以做到的。有時候殘留在輸入緩沖區(qū)中的數(shù)據(jù)垃圾會被下一個變量接收,但這會造成程序運行意外中止或得不到我們想要的結果,這時就需要事先清空輸入緩沖區(qū),可以選擇使用fflush(stdin)函數(shù)來完成這個工作。例如程序pro3.c,運行該程序時,假定用戶在輸入變量ascii的值時完全正確,但用戶卻永遠沒有機會從鍵盤輸入變量ch的值。程序的運行結果總是“很遺憾,您答錯了!”這顯然不是我們想要的結果。我們來分析一下為什么會得到這樣的運行結果。

通過scanf("%c",&ch)使變量ch獲取數(shù)據(jù)時,空格符、制表符和回車符都被當做有效字符。當程序運行到scanf(“%d”,&ascii)函數(shù)調用語句時,假定用戶輸入“49”,然后敲回車鍵。這時,變量ascii獲得值49,但回車符(其ASCII 碼為10)仍然在輸入緩沖區(qū)中。當程序運行到scanf(“%c”,&ch)函數(shù)調用語句時,系統(tǒng)直接從輸入緩沖區(qū)中取數(shù)據(jù)給變量ch,而不是讓用戶從鍵盤輸入。因此,變量ch得到的值就是回車符?;剀嚪腁SCIIi碼與9個數(shù)字字符的ASCII碼都不相等,因此,程序運行的結果總是“很遺憾,您答錯了!”如果改寫程序pro3.c為程序pro4.c,就可以解決這個問題。

雖然只添加了一條fflush(stdin);語句,但由于這個fflush(stdin)函數(shù)是可以清空輸入緩沖區(qū)的,這樣,輸入緩沖區(qū)中的數(shù)據(jù)垃圾就不會被變量ch接收了,變量ch的值也就只能通過鍵盤來輸入了。如果用戶輸入的字符的ASCII碼與前面輸入的變量ascii的值一樣,該程序的輸出結果就是“太棒了,您答對了!”。如果用戶輸入的字符的ASCII碼與前面輸入的變量ascii的值不一樣,該程序的輸出結果就是“很遺憾,您答錯了!”

但不是所有的C編譯系統(tǒng)都提供這個功能,因此,通過fflush(stdin)函數(shù)來清空輸入緩沖區(qū)的程序,其可移植性不夠好[1]??傊疫€是建議用gets()函數(shù)來解決問題,既可以防止用戶誤輸入非法字符,又可以清空輸入緩沖區(qū)。

4 scanf()函數(shù)不適合于包含空格或制表符的字符串

如果想通過scanf(“%s”,str)函數(shù)輸入字符串,那么str得到的字符串中不可能含有空格符或制表符,因為scanf()函數(shù)遇到空格符和制表符都會認為數(shù)據(jù)輸入結束。因此,要想使str獲得包含空格符或制表符的字符串,使用gets(str)函數(shù)比較好。

參考文獻:

[1] 蘇小紅, 王宇穎, 孫志崗.C語言程序設計[M]. 2版.北京: 高等教育出版社, 2013.

临海市| 罗山县| 工布江达县| 嘉荫县| 保山市| 泰顺县| 高州市| 疏勒县| 嘉善县| 宜昌市| 桐梓县| 府谷县| 司法| 苍梧县| 布拖县| 囊谦县| 成安县| 武汉市| 凤凰县| 邓州市| 临武县| 凤台县| 额济纳旗| 佛教| 安化县| 辉南县| 禄丰县| 登封市| 新平| 获嘉县| 宣威市| 大宁县| 龙南县| 永寿县| 东乌珠穆沁旗| 尉犁县| 富锦市| 宁波市| 逊克县| 晋城| 伊宁县|