C語言 getchar 函數全攻略:基礎用法、進階範例與常見問題解析

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;
}

這段程式會用 getcharputchar,將輸入內容直接顯示,直到偵測到 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 的差異

getcharscanf 都能取得輸入,但應用場景差異大。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;
}

當用戶輸入 lhq 時,程式會依指令執行對應動作。

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 迴圈清除緩衝區內殘留的換行字元。

最佳實踐

  1. 清除緩衝區:每次輸入時清理換行符號,避免影響後續操作。
  2. 錯誤處理:當 getchar 回傳 EOF 時應妥善處理,特別是在從檔案輸入時。
  3. 輸入限制:若需處理長字串或特殊輸入,建議使用 fgets,可指定緩衝大小,防止溢位。

8. 總結與進階學習方向

本文介紹了 getchar 函數的基本用法、進階應用,以及與 scanffgets 的比較,說明了 C 語言輸入處理的重點。getchar 雖然簡單,卻能靈活運用於各種場景,特別適合互動式程式或單字元輸入的場合。

推薦進一步學習的方向

  1. 深入運用 fgets 或 scanf:當需處理字串或數值輸入時,進一步學習 fgetsscanf 的應用會更有效。
  2. 檔案輸入getchar 不僅可用於標準輸入,也適合從檔案讀取資料。學習檔案 I/O 可拓展更多應用。
  3. 實踐錯誤處理:處理 EOF 或無效輸入等錯誤情境,可讓程式更穩定健壯。

只要掌握這些 C 語言的基本知識,就能設計出更實用的程式並拓展應用層面。

侍エンジニア塾