首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言標準輸入處理:多行讀取、strstr 過濾包含「ould」的行

     編輯:關於C語言

C語言標準輸入處理:多行讀取、strstr 過濾包含「ould」的行

從 `stdin` 逐行讀取,使用 `strstr` 過濾包含指定子串的行,是文本處理的基礎模式。本文提供健壯的 `getline` 實現、標準庫 `getline`/`fgets` 對比、緩衝區管理最佳實踐。

自定義 getline 實現 (教學用)

#define MAX_LINE 1000

// 讀取一行到 line,最多 limit 字元,返回讀取長度 (含 \n),EOF 返回 0
int my_getline(char *line, int limit) {
    assert(line);
    int i = 0;
    int ch;
    
    while (limit > 1 && (ch = getchar()) != EOF && ch != '\n') {
        line[i++] = ch;
        limit--;
    }
    
    if (ch == '\n') {
        line[i++] = '\n';
    }
    line[i] = '\0';
    return i;
}

主程式:過濾包含 "ould" 的行

int main() {
    char line[MAX_LINE];
    const char *target = "ould";
    
    while (my_getline(line, MAX_LINE) > 0) {
        if (my_strstr(line, target)) {
            printf("%s", line);  // line 已含 \n
        }
    }
    return 0;
}

標準庫方案對比 (推薦實務使用)

標準 getline 使用範例 (POSIX)

#define _GNU_SOURCE  // 或 _POSIX_C_SOURCE 200809L
#include 
#include 
#include 

int main() {
    char *line = NULL;
    size_t len = 0;
    ssize_t read;
    const char *target = "ould";
    
    while ((read = getline(&line, &len, stdin)) != -1) {
        if (strstr(line, target)) {
            fwrite(line, 1, read, stdout);  // 精確寫入 read 位元組
        }
    }
    
    free(line);  // getline 分配,需手動釋放
    return 0;
}

關鍵細節:輸入結束判斷

  • `getchar()` 返回 `EOF` (通常 -1) 表示檔案結束或錯誤
  • `fgets` 返回 `NULL` 表示 EOF 或錯誤
  • `getline` 返回 `-1` 表示 EOF 或錯誤
  • **交互式終端**:`Ctrl+D` (Unix) / `Ctrl+Z` (Windows) 發送 EOF

進階:帶行號、大小寫不敏感過濾

// strcasestr: 大小寫不敏感版 (BSD/GNU 擴展)
// 手寫版:
char *my_strcasestr(const char *h, const char *n) {
    if (!*n) return (char*)h;
    for (; *h; h++) {
        const char *p1 = h, *p2 = n;
        while (*p1 && *p2 && toupper(*p1) == toupper(*p2)) { p1++; p2++; }
        if (!*p2) return (char*)h;
    }
    return NULL;
}

// 帶行號輸出
int main() {
    char *line = NULL; size_t len = 0; ssize_t read;
    int line_no = 0;
    while ((read = getline(&line, &len, stdin)) != -1) {
        line_no++;
        if (my_strcasestr(line, "ould")) {
            printf("%4d: %s", line_no, line);
        }
    }
    free(line);
    return 0;
}

總結

**實務首選標準 `getline` (POSIX) 或 `fgets` (標準 C)**,自動處理緩衝區擴容、EOF、行結束符。教學理解 `my_getline` 邏輯:`getchar` 循環、緩衝區邊界保護、`\n` 保留、空終止。`strstr` 過濾模式可擴展為 `grep` 核心邏輯:正則表達式 → 有限自動機 → 高性能文本搜尋。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
函數簽名特點適用場景
fgets`char *fgets(char *s, int n, FILE *stream)`固定緩衝區、保留 \n、標準 C行長度可預期、嵌入式
getline`ssize_t getline(char **lineptr, size_t *n, FILE *stream)`**動態分配緩衝區**、自動擴容、POSIX行長度未知、現代 Linux/BSD
fgetln`char *fgetln(FILE *stream, size_t *len)`返回內部緩衝區指標、無 \0 終止、BSD高性能、零拷貝、只讀