C 標準庫提供兩種文件流模式,本質上都是字節序列,區別在於數據的解釋方式:
\n 分隔),整數/浮點數需轉換為字符串寫入。跨平台時可能進行換行符轉換(如 Windows \r\n ↔ Unix \n)。double 佔 8 字節,int 佔 4 字節,無任何轉換,精確保持內存位模式。關鍵洞察:文件中都是字節序列,關鍵在於程序如何解釋它們。字符 'a' 存儲為 ASCII 97,可被解讀為字符或整數 97。
FILE *fopen(const char *path, const char *mode);
int fclose(FILE *fp);
常用模式:
| 模式 | 說明 |
|---|---|
r | 只讀,文件必須存在 |
r+ | 讀寫,文件必須存在 |
w | 只寫,截斷或創建 |
w+ | 讀寫,截斷或創建 |
a | 追加寫入,創建或定位到末尾 |
a+ | 追加讀寫 |
注意:讀寫切換時需調用 fflush() 刷新緩衝區,或用 fseek()/rewind() 重定位指針,否則可能導致數據丟失或覆蓋。
int fputc(int c, FILE *stream); // 寫入字符
int fgetc(FILE *stream); // 讀取字符
// 對應宏版本:putc(), getc()
實際操作均通過內存緩衝區,非逐字符訪問磁盤。
int fputs(const char *s, FILE *stream); // 寫入字符串(不含 \0)
char *fgets(char *s, int size, FILE *stream); // 讀取一行(含 \n,以 \0 結尾)
int fprintf(FILE *stream, const char *format, ...);
int fscanf(FILE *stream, const char *format, ...);
int fflush(FILE *stream); // 強制寫入磁盤
void rewind(FILE *stream); // 等同 fseek(fp, 0, SEEK_SET)
FILE *fp = fopen("test.txt", "r");
if (!fp) {
fprintf(stderr, "無法打開文件: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
在模式字符串中添加 b:rb、wb、rb+ 等。
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
size:單個元素字節數nmemb:元素個數size * nmemblong ftell(FILE *stream); // 獲取當前位置
int fseek(FILE *stream, long offset, int whence); // 移動位置
// whence: SEEK_SET(開頭) SEEK_CUR(當前) SEEK_END(結尾)
int fgetpos(FILE *stream, fpos_t *pos); // 獲取位置(可移植)
int fsetpos(FILE *stream, const fpos_t *pos); // 設置位置
注意:追加模式(a/a+)下不可修改寫入位置,數據總寫入文件末尾。
char line[256];
while (fgets(line, sizeof(line), fp)) {
// 處理每一行,line 包含換行符
line[strcspn(line, "\n")] = '\0'; // 移除換行符
}
typedef struct {
int id;
double score;
char name[32];
} Student;
Student stu = {1001, 95.5, "張三"};
fwrite(&stu, sizeof(Student), 1, fp); // 寫入
fread(&stu, sizeof(Student), 1, fp); // 讀取
feof() 控制循環:while(!feof(fp)) 會多讀一次,應用讀取函數返回值判斷fread/fwrite:導致數據難以解讀fopen 返回值stderr 輸出錯誤信息,避免被重定向fflush() 或 fsync()(POSIX)確保落盤