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

C語言標準 I/O 深度解析:流、緩衝區、I/O 函數族與輸入緩衝清理

     編輯:關於C語言

流的抽象模型

  • 所有 I/O 視為位元組流,隱藏裝置細節
  • 兩類流:文字流(行導向、\n 結尾)與 二進位流(原始位元組)
  • UNIX 不區分兩者

三大標準流

流檔案指標檔案描述符預設裝置緩衝模式
標準輸入stdin0 (STDIN_FILENO)終端機行緩衝
標準輸出stdout1 (STDOUT_FILENO)終端機行緩衝
標準錯誤stderr2 (STDERR_FILENO)終端機無緩衝

程式啟動自動開啟,正常結束時自動 fclose 並沖洗緩衝區。

緩衝區三種模式

  1. 全緩衝:緩衝區滿才實際 I/O(磁碟檔案預設)
  2. 行緩衝:遇 \n 執行 I/O(終端機輸入輸出預設)
  3. 無緩衝:直接系統呼叫(stderr、setbuf(fp, NULL))

緩衝區控制函數

void setbuf(FILE *fp, char *buf);           // buf=NULL 關閉緩衝
int setvbuf(FILE *fp, char *buf, int mode, size_t size);
// mode: _IOFBF(全), _IOLBF(行), _IONBF(無)
// 必須在檔案開啟後、任何操作前呼叫

核心 I/O 函數族

單字元

int getc(FILE*); int fgetc(FILE*); int getchar(void);  // getchar() ≡ getc(stdin)
int putc(int, FILE*); int fputc(int, FILE*); int putchar(int); // putchar(c) ≡ putc(c, stdout)
// getc/putc 可能為巨集,fgetc/fputc 保證為函數

行導向

char *fgets(char *str, int n, FILE *fp);  // 讀最多 n-1 字元,含 \n
// gets() 不安全,禁用
int fputs(const char *str, FILE *fp);     // 寫字串,不寫 \0
int puts(const char *str);                // 寫字串 + 自動加 \n

格式化

int printf(const char *fmt, ...);
int fprintf(FILE *fp, const char *fmt, ...);
int sprintf(char *buf, const char *fmt, ...);
int snprintf(char *buf, size_t n, const char *fmt, ...);

int scanf(const char *fmt, ...);
int fscanf(FILE *fp, const char *fmt, ...);
int sscanf(const char *buf, const char *fmt, ...);

輸入緩衝區清理:正確與錯誤做法

❌ 錯誤:fflush(stdin)

C 標準未定義輸入流 fflush 行為。VC 允許,GCC/Clang 無效,不可移植。

❌ 不穩:setbuf(stdin, NULL)

關閉緩衝,但非標準保證行為,不建議依賴。

✅ 正確:手動讀取丟棄

int c;
while ((c = getchar()) != '\n' && c != EOF);

循環讀取直到換行或 EOF,標準、可移植、無副作用。

⚠️ 替代:scanf 格式字串

scanf("%*[^\n]%*c");  // 讀取並丟棄非換行字元,再丟棄換行符

但留下換行符需額外處理,易出錯,不推薦常用。

printf 實現機制

  • 變參函數,透過 <stdarg.h> 巨集(va_list、va_start、va_arg、va_end)遍歷參數
  • 解析格式字串,按轉換規格取對應引數
  • 內部常用 write() 系統呼叫輸出

效能提示

  • fgets/fputs + 手動處理 \n 最穩健
  • 大量資料用 fread/fwrite 區塊 I/O
  • 避免在效能關鍵路徑用 scanf/printf(格式解析開銷大)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved