1. 什麼是 getchar 函數?
getchar
函數是 C 語言中基本的輸入處理方式之一,可以從標準輸入讀取一個字元。當使用者從鍵盤輸入字元後,該函數會回傳該字元的 ASCII 碼,因此在需要簡單輸入時非常方便。例如,當需要逐一處理使用者輸入的每個字元時,可以使用這個函數。
getchar 函數的特點
- 從標準輸入取得一個字元:會等待使用者按下 Enter 鍵後才開始處理輸入內容。
- 回傳 ASCII 碼:取得的字元會以 ASCII 碼形式回傳。如果要當作字元處理,需要進行型別轉換(cast)。
getchar
特別適合用於簡單的用戶輸入或互動式程式設計。和其他輸入函數相比,它易於操作,因此經常用於 C 語言初學者的練習。
使用範例
以下是一個使用 getchar
的簡單輸入範例。
#include <stdio.h>
int main() {
int c;
printf("請輸入一個字元: ");
c = getchar();
printf("您輸入的字元: %c
", c);
return 0;
}
這個程式會取得使用者從鍵盤輸入的一個字元,然後將該字元顯示在螢幕上。例如,若輸入「A」,實際輸出如下:
請輸入一個字元: A
您輸入的字元: A
2. getchar 函數的基本用法
基本呼叫方法
getchar
函數的呼叫方式如下:
int getchar(void);
此函數不需參數,會讀取一個字元並回傳其 ASCII 碼。回傳型別為整數(int
),若發生錯誤則回傳 EOF
(End Of File)。
單純字元輸入的範例
上述範例中,getchar
讀取一個字元並將其顯示。當只需處理一個字元時,getchar
非常方便。
#include <stdio.h>
int main() {
int c;
printf("請輸入一個字元: ");
c = getchar();
printf("您輸入的字元: %c
", c);
return 0;
}
此程式會透過 getchar
取得字元,並用 printf
顯示輸入內容。
3. getchar 的進階應用
EOF(檔案結尾)與 getchar
getchar
不只可取得字元,也能在輸入結束時回傳 EOF
(End Of File)。例如,從檔案輸入或標準輸入時,輸入「Ctrl+Z」(Windows)或「Ctrl+D」(Unix)可偵測到 EOF。
以下是持續讀取字元直到 EOF 的程式範例:
#include <stdio.h>
int main() {
int c;
printf("請輸入字元(按 EOF 結束): ");
while ((c = getchar()) != EOF) {
putchar(c);
}
return 0;
}
這段程式會用 getchar
和 putchar
,將輸入內容直接顯示,直到偵測到 EOF。
多字元輸入
使用 getchar
也能讀取多個字元。下例會在遇到換行字元前,逐一顯示每個輸入的字元:
#include <stdio.h>
int main() {
int c;
printf("請輸入一串文字: ");
while ((c = getchar()) != '\n') {
printf("輸入的字元: %c\n", c);
}
return 0;
}
此程式會逐一取得字元並顯示,直到遇到 '\n'
(換行字元)。

4. EOF 與緩衝區處理
EOF 的作用
EOF(End Of File)代表檔案或標準輸入的結尾。getchar
在遇到 EOF 時會回傳 -1
,程式即可偵測並結束。EOF 通常用於標記檔案結束,但用鍵盤輸入時可以用特殊鍵產生。
緩衝與 getchar
由於 getchar
會將輸入內容緩衝,所有鍵入的字元會先存於緩衝區。例如連續呼叫多次 getchar
時,會取得下一個在緩衝區的字元。此特性會讓程式在遇到換行字元前無法進入下一步。
如果想忽略緩衝區內的換行字元,可這樣寫:
#include <stdio.h>
int main() {
int c;
printf("請輸入一個字元: ");
c = getchar();
while (getchar() != '\n'); // 忽略緩衝區內換行字元
printf("輸入的字元: %c\n", c);
return 0;
}
這個範例會先消耗掉換行符號,避免它影響後續輸入。
5. getchar 與其他輸入函數比較
getchar 與 scanf 的差異
getchar
和 scanf
都能取得輸入,但應用場景差異大。scanf
可指定格式,支援整數、浮點數、字串等多種資料型態輸入;而 getchar
只處理一個字元,簡單直觀。
scanf 範例:
#include <stdio.h>
int main() {
int num;
printf("請輸入一個數值: ");
scanf("%d", &num);
printf("您輸入的數值: %d\n", num);
return 0;
}
這個程式會用 scanf
取得整數輸入並顯示。scanf
可同時處理多種型態、多個數值。
getchar 與 fgets 的差異
fgets
不同於 getchar
,可以一次讀取多個字元(即一整行字串)。這在需要讀取長字串時特別實用。此外,fgets
可指定緩衝區大小,降低 scanf
常見的溢位風險。
fgets 範例:
#include <stdio.h>
int main() {
char str[100];
printf("請輸入一行文字: ");
fgets(str, sizeof(str), stdin);
printf("輸入的字串: %s", str);
return 0;
}
這個例子會用 fgets
讀入字串並顯示。fgets
會取得包含換行的整行內容,適用於處理多行資料。
getchar、scanf、fgets 的選擇建議
- getchar 適合需要逐一處理單個字元的場合,例如選單選擇或即時按鍵偵測。
- scanf 適合需要取得不同型態(數字、字串)輸入時使用,但建議加強錯誤處理。
- fgets 適合需輸入長字串或多行資料,且能避免緩衝區溢位。
6. 使用 getchar 實現互動式程式
getchar
常用於需與使用者互動的程式。這裡以根據輸入按鍵進行對應動作的範例說明。這種寫法常用於小型遊戲或選單系統。
範例程式:根據輸入字元操作選單
#include <stdio.h>
int main() {
char choice;
printf("請選擇選單 (a: 你好, b: 結束): ");
choice = getchar();
switch (choice) {
case 'a':
printf("你好!\n");
break;
case 'b':
printf("程式結束。\n");
break;
default:
printf("無效的選擇。\n");
}
return 0;
}
這個程式會根據輸入的 ‘a’ 或 ‘b’ 顯示不同訊息。利用 getchar
即可簡單實現選單功能。
進階程式:多指令對應
下例根據使用者輸入的特定字元執行不同指令:
#include <stdio.h>
int main() {
char command;
printf("請輸入指令 (l: 顯示清單, h: 問候, q: 結束): ");
command = getchar();
switch (command) {
case 'l':
printf("顯示清單。\n");
break;
case 'h':
printf("你好!\n");
break;
case 'q':
printf("程式結束。\n");
break;
default:
printf("無效的指令。\n");
}
return 0;
}
當用戶輸入 l
、h
、q
時,程式會依指令執行對應動作。
7. getchar 的注意事項與最佳實踐
常見問題:緩衝區處理
使用 getchar
時要注意,緩衝區內殘留的資料可能影響下一次輸入。例如呼叫一次 getchar
後,殘留的換行符號會被下次 getchar
取得。為避免這狀況,需清除緩衝區。
忽略換行字元的方法:
#include <stdio.h>
int main() {
int c;
printf("請輸入一個字元: ");
c = getchar();
while (getchar() != '\n'); // 忽略換行
printf("輸入的字元: %c\n", c);
return 0;
}
此程式於 getchar
取得一個字元後,會以 while
迴圈清除緩衝區內殘留的換行字元。
最佳實踐
- 清除緩衝區:每次輸入時清理換行符號,避免影響後續操作。
- 錯誤處理:當
getchar
回傳EOF
時應妥善處理,特別是在從檔案輸入時。 - 輸入限制:若需處理長字串或特殊輸入,建議使用
fgets
,可指定緩衝大小,防止溢位。
8. 總結與進階學習方向
本文介紹了 getchar
函數的基本用法、進階應用,以及與 scanf
、fgets
的比較,說明了 C 語言輸入處理的重點。getchar
雖然簡單,卻能靈活運用於各種場景,特別適合互動式程式或單字元輸入的場合。
推薦進一步學習的方向
- 深入運用 fgets 或 scanf:當需處理字串或數值輸入時,進一步學習
fgets
和scanf
的應用會更有效。 - 檔案輸入:
getchar
不僅可用於標準輸入,也適合從檔案讀取資料。學習檔案 I/O 可拓展更多應用。 - 實踐錯誤處理:處理
EOF
或無效輸入等錯誤情境,可讓程式更穩定健壯。
只要掌握這些 C 語言的基本知識,就能設計出更實用的程式並拓展應用層面。