C/C++ fread 用法與範例

本篇 ShengYu 介紹 C/C++ fread 的用法與範例,C/C++ 可以使用 fread 從文字檔裡讀取內容出來,在 fread 函式的引數裡可以指定要讀取幾個 bytes 字元,fread 除了從檔案裡讀取文字以外還能從標準輸入讀取文字,詳見本篇範例。

C/C++ 要使用 fread 的話需要引入的標頭檔 <stdio.h>,如果要使用 C++ 的標頭檔則是引入 <cstdio>
fread 函式原型為

1
size_t fread(void * ptr, size_t size, size_t count, FILE * stream);

ptr:指向一塊記憶體的指標,該塊記憶體至少要(size * count)個的大小
size:要讀取的每一個元素大小(單位為 byte)
count:要讀取的元素數量
stream:指向 FILE 物件的指標

以下 C/C++ fread 的用法介紹將分為這幾部份,

  • C/C++ fread 從檔案讀取文字的基本用法
  • C/C++ fread 從檔案多次讀取文字
  • C/C++ fread 從標準輸入讀取文字
  • C/C++ fread 讀取二進制檔
  • C/C++ fread 讀取二進制檔資料到 struct 裡

那我們開始吧!

C/C++ fread 從檔案讀取文字的基本用法

這邊介紹 C/C++ fread 從檔案讀取文字的基本用法,以下範例示範 C/C++ 用 fread 來讀取文字檔的內容,假設我們要讀取一個 input.txt,input.txt 內容長這樣如下,

input.txt
1
2
hello world
123456

那麼用 fread 來讀取文字檔的程式碼如下,在使用 fread 前要先 fopen 開檔成功才能進行檔案內容讀取,fopen 開檔回傳 NULL 表示開檔失敗,如果不是 NULL 表示開檔成功。

接著使用 fread 進行讀取,這邊示範用 fread 讀取 1024 bytes,如果檔案內容小於 1024 bytes 的話,這次的 fread 就會讀完整個檔案的內容且回傳讀取了多少 bytes,如果檔案內容大於 1024 的話,這次的 fread 最多只會讀取 1024 bytes,你需要再次呼叫 fread 來讀取剩下的檔案內容,這個 fread 第三個引數的 1024 數字是可以調整的,但不能超過 buffer 變數的大小,接著將 buffer 用 printf 印出來,最後 fclose 關檔,

cpp-fread.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// g++ cpp-fread.cpp -o a.out
#include <stdio.h>

int main() {
FILE *fp;
char buffer[1024];
size_t numread;

fp = fopen("input.txt", "r");
if (fp == NULL) {
printf("failed to open the file.\n");
return 1; // EXIT_FAILURE
}

numread = fread(buffer, sizeof(char), 1024, fp);
printf("read %lu bytes\n", numread);
printf("%s\n", buffer);
fclose(fp);
return 0;
}

fread 讀取完後用 printf 印出來結果輸出如下,

1
2
hello world
123456

C/C++ fread 從檔案多次讀取文字

這邊示範 C/C++ fread 從檔案多次讀取文字的範例,搭配一個 while 無窮迴圈進行 fread 讀取,並且每次只讀 10 的元素,直到 fread 回傳的 numread 為 0 才跳離 while 迴圈,然後 fclose 關檔,

cpp-fread2.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// g++ cpp-fread2.cpp -o a.out
#include <stdio.h>
#include <string.h>

int main() {
FILE *fp;
char buffer[1024];
size_t numread;

fp = fopen("input.txt", "r");
if (fp == NULL) {
printf("failed to open the file.\n");
return 1; // EXIT_FAILURE
}

while (1) {
memset(buffer, 0, 1024);
numread = fread(buffer, sizeof(char), 10, fp);
if (numread == 0)
break;
printf("read %lu bytes\n", numread);
printf("%s\n", buffer);
}
fclose(fp);
return 0;
}

結果輸出如下,

1
2
3
4
5
read 10 bytes
hello worl
read 9 bytes
d
123456

C/C++ fread 從標準輸入讀取文字

C/C++ fread 除了從檔案裡讀取文字以外也可以用來從標準輸入讀取文字,範例如下,標準輸入為 stdin 就不需要像檔案一樣開檔了,

cpp-fread3.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// g++ cpp-fread3.cpp -o a.out
#include <stdio.h>

int main() {
char buffer[32];
size_t numread;

printf("input: ");
numread = fread(buffer, sizeof(char), 10, stdin);
printf("read %lu bytes\n", numread);
printf("%s\n", buffer);

return 0;
}

啟動程式後輸入 hello world 123 的輸出如下,

1
2
3
input: hello world 123
read 10 bytes
hello worl

C/C++ fread 讀取二進制檔

這邊介紹 C/C++ fwrite 讀取二進制檔,假如只讀取單純一筆 int 的資料的話,範例如下,

cpp-fread4.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// g++ cpp-fread4.cpp -o a.out
#include <stdio.h>

int main() {
int num;

FILE *fp = fopen("input.bin", "rb");
if (fp == NULL) {
printf("failed to open the file.\n");
return 1; // EXIT_FAILURE
}

size_t numread = fread(&num, sizeof(int), 1, fp);
printf("read %lu bytes\n", numread);
printf("%d\n", num);
fclose(fp);
return 0;
}

結果輸出如下,

1
2
read 1 bytes
5

假如要讀取 int 陣列的資料的話,範例如下,

cpp-fread5.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// g++ cpp-fread5.cpp -o a.out
#include <stdio.h>

int main() {
int arr[3];

FILE *fp = fopen("input.bin", "rb");
if (fp == NULL) {
printf("failed to open the file.\n");
return 1; // EXIT_FAILURE
}

size_t numread;
numread = fread(&arr, sizeof(int), 3, fp);
// or
/*for (int i = 0; i < 3; i++) {
numread += fread(&arr[i], sizeof(int), 1, fp);
}*/
printf("read %lu bytes\n", numread);
printf("%d, %d, %d\n", arr[0], arr[1], arr[2]);
fclose(fp);
return 0;
}

結果輸出如下,

1
2
read 3 bytes
1, 2, 3

上例中也可以搭配用 for 迴圈的方式寫入,

1
2
3
for (int i = 0; i < 3; i++) {
numread += fread(&arr[i], sizeof(int), 1, fp);
}

要用 fwrite 將資料寫入二進制檔的話可以看看這篇

C/C++ fread 讀取二進制檔資料到 struct 裡

這邊示範 C/C++ fread 讀取二進制檔資料到 struct 裡,先用 fread 讀一個 int 知道有幾筆 struct 的資料後,之後再用 for 迴圈搭配 fread 讀取 count 次 struct 的資料,

cpp-fread6.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// g++ cpp-fread6.cpp -o a.out
#include <stdio.h>

struct Student {
int id;
char name[4];
int age;
};

int main() {
struct Student st[10] = {0};
int count;

FILE *fp = fopen("input.bin", "rb");
if (fp == NULL) {
printf("failed to open the file.\n");
return 1; // EXIT_FAILURE
}

fread(&count, sizeof(int), 1, fp);
printf("count: %d\n", count);

for (int i = 0; i < count; i++) {
fread(&st[i], sizeof(struct Student), 1, fp);
printf("id: %d, name: %s, age: %d\n",
st[i].id, st[i].name, st[i].age);
}
fclose(fp);
return 0;
}

結果輸出如下,

1
2
3
4
count: 3
id: 1, name: ab, age: 18
id: 2, name: cd, age: 19
id: 3, name: ef, age: 20

更好的寫法是讀完筆數後,去 new 動態記憶體配置對應的 struct 筆數,如下所示,跟上例不同的地方還有這次我把 fread 一次讀取 count 筆 struct 資料,

cpp-fread7.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// g++ cpp-fread7.cpp -o a.out
#include <stdio.h>

struct Student {
int id;
char name[4];
int age;
};

int main() {
int count;

FILE *fp = fopen("input.bin", "rb");
if (fp == NULL) {
printf("failed to open the file.\n");
return 1; // EXIT_FAILURE
}

fread(&count, sizeof(int), 1, fp);
printf("count: %d\n", count);

struct Student *st = new Student[count];
fread(st, sizeof(struct Student), 3, fp);

for (int i = 0; i < count; i++) {
printf("id: %d, name: %s, age: %d\n",
st[i].id, st[i].name, st[i].age);
}
fclose(fp);
return 0;
}

結果輸出同上。要如何用 fwrite 將 struct 寫入二進制的範例可以看這篇

以上就是 C/C++ fread 的用法與範例介紹,
如果你覺得我的文章寫得不錯、對你有幫助的話記得 Facebook 按讚支持一下!

其它相關文章推薦
如果你想學習 C++ 相關技術,可以參考看看下面的文章,
C/C++ 新手入門教學懶人包
C/C++ fopen 用法與範例
C/C++ fgets 用法與範例
C/C++ fwrite 用法與範例
C/C++ fputs 用法與範例
C/C++ fclose 用法與範例