如何確保獲取的輸入為整數-C語言基礎
這一篇探討的是如何確保你輸入的資料是一個整數。雖然標題用的是這個,但我其實真正想要探討的內容是 “在程式除錯的過程中,需要注意把輸入快取區中的上一次輸入的殘留資訊清理乾淨,以免影響下一次的輸入。” 但由於這個內容太過於冷門,且不迎合人們利用搜索引擎查詢問題時關鍵字的搜尋。所以不太適合用於做標題,於是便利用了文章中例子所實現的功能來作為標題。屬於c語言基礎篇。
本來是想要把程式碼改成精簡版直接用來說明的,但是在精簡程式碼的過程中,覺得這個程式碼精簡的過程挺重要的,所以想要單獨的廢話一兩句(建議程式設計小清新看一下,大佬的話感興趣可以審閱一下也可以直接跳過)。
對於程式設計這件事情,同一個需求,一百個人可能有一百篇不一樣的程式碼。雖然都可以實現功能,但有些人的程式碼跑起來就是比別人的程式碼效率高。同樣效率的程式碼,有些人的程式碼對於記憶體的佔用,就是比別人的小很多。當然,在程式設計這件事上面,時間和空間不可兼得(一個很簡單的例子就是全域性變數,全域性變數是一個很方便效率很高的東西,程式碼程式設計的過程中合理的使用全域性變數,可以有效的提高程式的執行效率。但同時你也要清楚,全域性變數是與程式共存亡的,也就是說整個程式的執行階段都需要分配一塊記憶體來儲存這個變數,這其實是在用空間的佔用來換取時間的快速)。所以一個好的程式,往往是能在時間和空間上面找到合理平衡點的程式。
個人認為一個程式設計師對於程式的追求應該有三個階段。
第一個階段是程式程式碼的精簡,
第二個階段是在第一個階段的基礎上提升程式的效率。
第三個階段是在第二個階段的基礎上壓縮程式的空間。
很慚愧的說,本人現在還在第一個階段中掙扎徘徊。
好了,步入正題,這裡我用的例子功能為——從鍵盤接收一個整數,將其轉換成其ASCIL碼值所對應的字元輸出(就是用序號查ASCIL碼錶)。
想要實現這個需求的話,我們先分析一下整體思路,這是我老師教我的。雖然我挺不喜歡這個環節的,每次聽老師講思路分析都會犯困,我倒是挺喜歡直接看程式碼的。但有時對於一些比較複雜的問題,如果不冷靜下來捋一下思路,常常又會無從下手。
在這個例子裡面,我們的思路很明確,既然需要把一個輸入的整數轉換為ASCIL碼數值,那麼我們首先需要從鍵盤接收一個整數,這裡用的是scanf()
函式來接收鍵盤資料,然後通過返回值來判斷是否讀取到了需要的資料。而 scanf()
函式的返回值有兩種可能,要麼返回接收到的資料個數,要麼返回0。
利用 scanf() 函式本身的特性,這一步只有當輸入資料的第一個是整型的時候, scanf()
函式的返回值才是1,否則就會返回0。這已經可以斷絕掉輸入的資料不是整型的可能了。
那是不是說只要我判斷一下返回值是否等於1就可結束任務呢?如果我同時輸入兩個整形資料呢?
當然,在這個程式裡面是沒有問題的,因為這個程式只要接收到了第一個整形資料後,便會退出迴圈,結束程式。由於程式已經死掉了,後面輸入的內容便會跟著程式一起被系統釋放掉。
但是如果你的程式很大很大,在這裡接收了使用者輸入後,後面也還要接收使用者的輸入,這裡就會出現問題了。由於你在這邊連續輸入了多個數據,且第一個是整形,程式執行到這裡的時候,僅僅只讀取了第一個整型資料,而後面的殘留資料被留在了快取區,在程式下一次讀取鍵盤資料的時候,這些殘留資料就會被錯誤輸入到程式中,就有可能導致程式出現錯誤。
那麼既然我們意識到了同時輸入多個數據可能會造成程式的意外錯誤,那麼在這裡我們就不能簡單的判斷scanf的返回值是否等於1了事,在程式得到了這個資料後還要判斷一下這個資料後面是否還有別的資料。判斷過程在程式碼中體現。
最後就是處理好判斷的結果就行了,如果讀取正常要怎麼處理,如果讀取不正常又要怎麼處理。
好了先看原版程式碼。
#include <stdio.h>
int main(void)
{
int pw;//這個變數是用來接受輸入的
int i;//臨時變數,儲存返回值用於判斷
while(1)
{
i = scanf("%d", &pw);
//這一步就是判斷輸入的資料是否合法,且輸入的僅僅是一個整數
if(i == 1 && getchar() == '\n')
break;
else
{
// 溫馨提示一下
if(i == 1)
printf("請僅輸入一個整數!\n");
else
printf("你輸入的不是整數,請再來一遍!\n");
//這一步就是將快取區中的非法格式資料拿掉的一步了
while(1)//清空快取區
{
char c = getchar();
if(c == '\n')
break;
}
}
}
printf("你輸入的數值轉為字元為:%c\n", (char)pw);
return 0;
}
以下是精簡版的程式碼。
#include <stdio.h>
int main(void)
{
int pw;//這個變數是用來接受輸入的
//這一步就是判斷輸入的資料是否合法,且輸入的僅僅是一個整數
while(!(scanf("%d", &pw) && getchar() == '\n'))
{
while(getchar() != '\n');//清空快取區
printf("你輸入的資料有誤,請再輸一遍!\n");//溫馨提醒一下
}
printf("你輸入的數值轉為字元為:%c\n", (char)pw);
return 0;
}
由於是第一篇部落格還不太擅長組織文章的結構和對於語言的表達,原諒我把如此簡單的問題複雜的扯了這麼一大篇。