getchar()函式的詳解以及使用時需要注意的一些細節-C語言基礎
這篇文章要探討的是“getchar()函式的詳解以及使用時需要注意的一些細節”。涉及getchar()函式的應用和需要注意的問題。屬於C語言基礎篇(持續更新
)。
在C語言的學習過程中,我們常常需要接收鍵盤的輸入,在接收鍵盤輸入的過程中涉及到的函式通常有三個
getchar()
、scanf()
、fgets()
。這三個函式各自的功能各不相同,需要我們根據不同的需求條件來選擇不同的輸入接收函式。而在這三個函式的使用過程中,有一些細節需要我們注意一下。所以接下來的三篇文章就是分別介紹這三個函式的。
getchar()(函式原型:int getchar(void))
一般用法:
char c = getchar();
getchar()函式的作用很簡單,從輸入快取區中讀取一個字元,讀取到的字元儲存在返回值裡面。
getchar()函式注意事項1:
對於你輸入的任何資料,getchar() 都會把它們當作是字元來處理,而且每次只獲取一個字元。例如你輸入“11
”,getchar() 並不會把它當做“11
”來處理,而是把它當做兩個‘1
’來處理。同理,你輸入“3.14
”它也不會當成“3.14
”來處理而是當做‘3
’、‘.
’、‘1
’、‘4
’來處理,需要特別說明的是,像是換行符(\n
)、回車符\歸位符(\r
)、縮排符(\t
)之類的轉義字元,它們雖然在程式碼中的表示和我們平時說明中用的是兩個字元。但實際上它們在機器中儲存和還是以一個字元來儲存/
’和‘n
’。我們表示是這麼表示,但在機器內部它就還是一個字元而已。
對於換行符(\n)和回車符(\r)的區別我在這裡簡單說一下。
換行符(\n)的作用是換一行輸出。回車符(\r)的作用是把游標回到該行的行首。這兩者的概念之所以有很多人會疑惑,這是由於我們平時的習慣稱呼導致的。我們習慣性的把鍵盤上面那個換行回車鍵稱為回車鍵,事實上它應該是兩個鍵的混合(\r\n)。
同時也因為我們現在的開發環境便捷導致的,在一般的開發環境下面換行符(\n)就已經相當於同時具備換行回車(\r\n)的功能了,所以我們平時對於(\n)用的就比較多,(\r)就比較少用了。
但是如果在一些不那麼高階的開發環境(例如小型嵌入式系統)下面的話,情況就不一樣了,換行符(\n)就僅僅只是換行而已,你原本的游標在一行的哪個位置,就還在新行的哪個位置。你若想要游標回到行首,你就得手動輸出回車符(\r)。
getchar()函式注意事項2:
getchar()
函式是會阻塞等待的。在程式呼叫getchar()
函式的時候如果快取區中沒有資料的話,getchar()
函式便會阻塞等待使用者的輸入。
getchar()函式注意事項3:
用getchar()
的返回值做判斷的時候,需要考慮到是否儲存保留的問題。無論你是否接收getchar()
的返回值,只要你呼叫了getchar()
,那麼快取區中就會被讀取走一個字元。
這裡用一個我曾經犯錯誤的例子來說明一下:
#include <stdio.h>
int main(void)
{
char c[100] = {0};//建立一個數組來儲存輸入
int i = 0;//記錄一共輸入了幾個字元,方便後面輸出。
while(1)
{
if(getchar() == ‘\n’)//先判斷輸入的是否是回車鍵
break;
c[i] = getchar();//再把判斷好的輸入值儲存起來
i++;
}
for(int k = 0;k < i;k++)
printf("%c", c[k]);//把儲存的值輸出
printf("\n");
return 0;
}
這個程式所要實現的功能是“程式執行之後,持續的讀取鍵盤的輸入一直到使用者輸入換行符為止,然後退出迴圈輸出讀取到的內容”。
先看一下這個程式出現的問題吧:
-
執行的時候如果你輸入資料的字元個數為單數的時候,你需要輸入兩次回車才能結束程式,而且程式讀取到的輸入總是使用者輸入的一半,而且是隔一個讀取一個那種,最後面還多輸出一個回車。
-
執行的時候如果你輸入資料的字元個數為雙數的時候,就還算正常,僅僅只是輸入少一半而已。
其實仔細分析一下,就不難看出,這兩種情況是可以歸類為一種情況的。如果你把第一種情況中第一次輸入的回車也看作一個字元的話,你就會發現,只有當你輸入資料的字元個數為
雙數
的時候,你下一個輸入的回車
才能結束程式(也就是說如果我只在單數的時候輸入回車,那麼這個程式就會一直執行下去,直到一開始給的陣列記憶體大小不夠,程式訪問到了非法記憶體才會結束)。也是因為第一次輸入的回車被算進整體輸入裡面去了,才導致了第一種情況的時候結尾多了個換行。
再說一下原因吧:
出現這種情況的原因很簡單,相信不少人也已經看出來了。在這個例子中我在判斷輸入是否是“\n”的時候就已經讀取走一個字元了,後面再儲存的時候已經是第二個字元
了,所以就造成了“讀取到的輸入只有實際輸入的一半這種情況”。
解決辦法:
解決辦法也不難,犧牲一個臨時變數來儲存輸入的資料,再判斷是否是回車鍵即可。
#include <stdio.h>
int main(void)
{
char c[100] = {0};//儲存輸入資料用的陣列
int i = 0;//記錄輸入的字元個數方便輸出
char z = 0;//解決方法就是加入臨時變數來先儲存再判斷
while(1)
{
z = getchar();//先儲存輸入的資料
if(z == ‘\n’)//再判斷
break;//如果是回車就退出迴圈
c[i] = z;//如果不是回車就儲存
i++;//計數加一
}
for(int k = 0;k < i;k++)
printf("%c", c[k]);//把儲存的資料輸出
printf("\n");
return 0;
}
再附上這個例子的精簡版程式碼:
#include <stdio.h>
int main(void)
{
int i = 0;
char c[100] = {0};
while((c[i++] = getchar()) != '\n');
for(int k = 0;k <= i;k++)
printf("%c", c[k]);
return 0;
}