函式原型
size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
參數說明
buffer:接收資料的記憶體緩衝區,大小至少 size * count 位元組。
size:單一元素大小(位元組)。
count:要讀取的元素個數。
stream:輸入檔案流指標。
回傳值
- 成功:回傳實際讀取的元素個數(等於
count 表示完整讀取)。
- 失敗或 EOF:回傳值
< count。需配合 ferror()、feof() 判斷原因。
完整範例:寫入並讀回字串
#include <stdio.h>
#include <string.h>
int main(void)
{
FILE *fp;
char msg[] = "this is a test";
char buf[20];
if ((fp = fopen("DUMMY.FIL", "w+")) == NULL) {
perror("fopen");
return 1;
}
// 寫入:含結尾 \0,共 strlen+1 位元組
fwrite(msg, 1, strlen(msg) + 1, fp);
// 移回檔頭
fseek(fp, 0, SEEK_SET);
// 讀取
fread(buf, 1, strlen(msg) + 1, fp);
printf("%s\n", buf);
fclose(fp);
return 0;
}
MSDN 風格範例:讀寫字元陣列
FILE *fp;
char list[30];
int i, numread, numwritten;
if ((fp = fopen("fread.out", "w+t")) != NULL) {
for (i = 0; i < 25; i++) list[i] = 'z' - i;
numwritten = fwrite(list, sizeof(char), 25, fp);
printf("Wrote %d items\n", numwritten);
fclose(fp);
}
if ((fp = fopen("fread.out", "r+t")) != NULL) {
numread = fread(list, sizeof(char), 25, fp);
printf("Read %d items\n", numread);
printf("%.25s\n", list);
fclose(fp);
}
關鍵使用技巧
- 結構體整塊讀寫:
struct Record { int id; char name[20]; float score; };
struct Record r;
fread(&r, sizeof(r), 1, fp); // 單次讀取整個結構體
- 大量資料分塊讀取:避免單次
count 過大導致堆疊/緩衝區問題,迴圈分批讀取。
- 檢查回傳值:
if (fread(buf, 1, n, fp) != n) { handle_error(); }
- 文字 vs 二進制模式:Windows 下
\"rb\"/\"wb\" 避免 \r\n 轉換;Linux 無差異。
常見錯誤
size、count 顛倒 → 讀取量錯誤。
- 緩衝區太小 → 緩衝區溢位。
- 忽略回傳值 → 讀取不完整卻當作成功。
- 用於文字檔逐行讀取 → 應改用
fgets 或 getline。
fread vs fgets 對照
| 場景 | 推薦函式 |
| 二進制檔案、固定大小結構體、大量資料 | fread |
| 文字檔逐行、不定長度行、需保留換行 | fgets |
| 格式化文字掃描 | fscanf |