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

APUE 學習筆記(一):深入理解文件 I/O 與標準庫函數

     編輯:關於C語言

APUE 學習筆記(一):深入理解文件 I/O 與標準庫函數

《UNIX 環境高級編程》(APUE)是系統程式設計的經典教材。本文作為學習系列第一篇,重點整理文件 I/O 相關核心概念與標準 I/O 函數族的使用細節,所有內容基於 Linux 環境驗證。

核心概念:文件位置指針

標準 I/O 庫為每個打開的流維護一個文件位置指針,自動記錄下一次讀寫位置。程式員無需手動管理,但理解其機制對掌握 fseek、ftell、rewind 等定位函數至關重要。

標準 I/O vs 系統 I/O

  • 標準 I/O:可移植性高,緩衝機制豐富,但性能略遜於系統調用。
  • 系統 I/O:直接調用內核(open/read/write),性能高,但可移植性較差。

關鍵函數詳細解析

1. fopen — 打開流

FILE *fopen(const char *path, const char *mode);

常用模式:

模式說明
r唯讀,指針指向文件首,文件必須存在
r+讀寫,指針指向文件首,文件必須存在
w唯寫,不存在則創建,存在則截斷為 0,指針指向文件首
w+讀寫,創建/截斷規則同 w
a追加寫入,不存在則創建,指針指向文件尾
a+讀取與追加,讀指針指向文件首,寫入總在文件尾

返回 FILE* 指針,失敗返回 NULL 並設 errno。

2. fclose — 關閉流

int fclose(FILE *fp);

釋放資源,刷新緩衝區。使用後指針失效,切勿再次解引用。

3. fgets — 讀取字符串

char *fgets(char *s, int size, FILE *stream);

從流讀取最多 size-1 字符,遇 \n、EOF 或錯誤停止,自動補 \0。返回 s 或 NULL。比 gets 安全,但仍可能截斷長行。

4. fread/fwrite — 二塊數據讀寫

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

關鍵點:返回值是成功讀寫的對象個數,而非字節數。習慣用 size=1, nmemb=N 逐字節讀寫,避免最後一個對象不完整導致計數偏差。

5. atoi 族 — 字符串轉整數

int atoi(const char *nptr);
long atol(const char *nptr);
long long atoll(const char *nptr);

跳過前導空白,轉換連續數字字符,遇非數字停止。若首字符非數字返回 0。無錯誤檢測機制,生產代碼建議用 strtol。

6. printf 族 — 格式化輸出

返回值:成功輸出的字符數(不含 \0)。

snprintf 安全格式化:

int snprintf(char *str, size_t size, const char *format, ...);

最多寫入 size-1 字符,強制以 \0 結尾,防止緩衝區溢出。可用於數字轉字符串、多字符串拼接。

7. scanf 族 — 格式化輸入

警告:%s 無長度限制,極易導致緩衝區溢出。讀取用戶輸入請改用 fgets + sscanf 或手動解析。

8. fseek/ftell/rewind — 流定位

int fseek(FILE *stream, long offset, int whence);
long ftell(FILE *stream);
void rewind(FILE *stream);

whence:SEEK_SET(文件首)、SEEK_CUR(當前)、SEEK_END(文件尾)。

局限:參數/返回值為 long,僅支援 ±2GB。大文件請用 fseeko/ftello(POSIX,需 _POSIX_C_SOURCE)。

rewind(stream) 等價 fseek(stream, 0L, SEEK_SET) 並清除錯誤標誌。

9. getline — 動態讀取整行

ssize_t getline(char **lineptr, size_t *n, FILE *stream);

自動分配/擴展緩衝區,無長度限制。GNU 擴展,編譯需 -D_GNU_SOURCE 或代碼開頭 #define _GNU_SOURCE。攜帶性要求高的項目建議自行封裝。

小結

標準 I/O 函數族是 C 語言文件操作的基石。掌握緩衝模式、返回值語義、錯誤處理與大文件支援細節,能顯著提升代碼健壯性與可移植性。下一篇將探討系統級 I/O 與文件元數據操作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved