C 語言安全讀取字串:fgets 函數完整教學與實用範例

1. 前言

fgets 函數是 C 語言中用來安全讀取字串的標準函式庫函數。作為傳統 gets 函數的安全替代方案,它被廣泛應用。本文將詳細介紹 fgets 函數的用法、優缺點,以及如何進行安全的輸入處理。

2. fgets 函數的基本用法

2.1 fgets 的語法與參數

fgets 的基本語法如下:

char *fgets(char *str, int n, FILE *stream);
  • str:用來儲存讀取字串的緩衝區
  • n:要讀取的最大字元數(緩衝區大小)
  • stream:輸入串流(通常為 stdin

2.2 範例程式碼介紹

以下是使用 fgets 的基本範例。

char buffer[50];
fgets(buffer, 50, stdin);
printf("輸入的字串:%s", buffer);

這段程式會從使用者讀取最多 49 個字元(加上結尾的 Null 字元為 50),並將結果輸出。

3. fgets 的優點與問題

3.1 相較於 gets 的安全性

gets 函數容易造成緩衝區溢位,存在極高的資安風險。相較之下,fgets 可以指定讀取的字元數,有效避免緩衝區溢位問題。

3.2 換行字元問題與緩衝區處理

fgets 在讀取時會將換行字元一併讀入,可能導致出現非預期的換行。此外,因為緩衝區有大小限制,如果輸入超過緩衝區容量,剩下的資料會殘留在輸入串流中。

4. 安全輸入處理的方法

4.1 移除換行字元的方法

fgets 讀取字串時,結果中可能含有換行字元。可使用下列程式碼將其移除:

char *newline = strchr(buffer, '\n');
if (newline) {
    *newline = '\0';
}

這樣可將換行字元替換為結尾的 Null 字元,讓字串更乾淨。

4.2 清除緩衝區的方法

若輸入超過緩衝區大小,輸入串流中可能會殘留資料。為了避免這個問題,可以加上清除剩餘資料的程式:

while ((getchar()) != '\n' && !feof(stdin));

這段程式會將輸入串流中直到遇到換行字元或檔案結尾前的內容全部清除。

5. 使用 fgets 時的注意事項

5.1 錯誤與例外處理的重要性

fgets 讀取成功時會回傳指標,若失敗則回傳 NULL。正確的錯誤處理相當重要。

if (fgets(buffer, sizeof(buffer), stdin) == NULL) {
    // 錯誤處理
}

5.2 最佳實踐

使用 fgets 時,務必注意緩衝區大小及錯誤處理。記得驗證輸入資料,預防緩衝區溢位,確保程式安全。

6. fgets 的實用範例

6.1 輸入驗證與清洗(Sanitizing)

處理使用者輸入時,驗證及清洗資料非常重要。下例僅接受純數字輸入:

char input[10];
if (fgets(input, sizeof(input), stdin) != NULL) {
    // 移除換行字元
    char *newline = strchr(input, '\n');
    if (newline) {
        *newline = '\0';
    }

    // 僅接受數字
    if (strspn(input, "0123456789") == strlen(input)) {
        printf("輸入的數字:%s\n", input);
    } else {
        printf("無效輸入,請僅輸入數字。\n");
    }
}

7. 總結

fgets 函數是 C 語言中安全讀取字串的好工具。比起 gets 更安全,能降低緩衝區溢位的風險。但在使用時,須注意換行字元處理及清除緩衝區等細節。善用本文技巧,可確保安全且高效的輸入處理。