Unix 哲學「一切皆文件」的極致體現:cat 將標準輸入或指定文件內容原樣輸出到標準輸出。本文給出極簡 C 實現(< 30 行),涵蓋參數解析、文件流操作、錯誤處理、EOF 判斷。
#include#include void file_copy(FILE *in, FILE *out) { int c; while ((c = getc(in)) != EOF) putc(c, out); } int main(int argc, char *argv[]) { FILE *fp; char *prog = argv[0]; // 程序名,用於錯誤信息 if (argc == 1) { // 無參數:stdin → stdout file_copy(stdin, stdout); } else { while (--argc > 0) { if ((fp = fopen(*++argv, "r")) == NULL) { fprintf(stderr, "%s: 無法打開 %s\n", prog, *argv); exit(1); } file_copy(fp, stdout); fclose(fp); } } if (ferror(stdout)) { // 輸出流錯誤檢查 fprintf(stderr, "%s: 輸出錯誤\n", prog); exit(2); } exit(0); }
getc/putc:單字符讀寫,自動處理緩衝,返回 int 以容納 EOF。argv[0] 保存程序名,錯誤信息更友好。--argc > 0 + *++argv:經典參數遍歷慣用法,跳過程序名依次取文件名。ferror(stdout):檢測輸出錯誤(如管道破裂、磁盤滿),非零則報錯退出。exit(0/1/2):區分退出碼,便於腳本判斷:0=成功,1=輸入錯誤,2=輸出錯誤。gcc mini_cat.c -o mycat echo "hello" | ./mycat # 管道輸入 ./mycat file1.txt file2.txt # 多文件連接 ./mycat < input.txt > output.txt # 重定向
-n 選項顯示行號(需狀態機跟踪換行)。-b 非空行編號。- 表示 stdin(如 cat - file)。fopen(..., "rb") 避免換行轉換。這個 mini cat 雖小,但完整演示了 C 語言標準 I/O 庫的核心用法:**流抽象、字符級拷貝、參數處理、錯誤碼規範**。是理解 Unix 文件系統接口與 C 運行庫交互的最佳入門程序。