Like Share Discussion Bookmark Smile

J.J. Huang   2019-12-09   C   瀏覽次數:

C語言 - 第四十章 | 檔案 I/O - 隨機存取檔案

隨機存取檔案

使用資料流游標,可以自由的移動至檔案中指定的位置進行讀取或寫入的動作,通常隨機存取檔案會使用二進位模式進行,文字模式開啟的檔案並不適合作隨機存取的動作。

如何利用隨機存取來讀寫所有的資料,必須視你的需求而定,需求決定你的資料結構,這邊以一個最簡單的例子來示範隨機存取,寫入檔案時都是使用固定大小的struct,由於資料大小固定,這可以方便明確的指定檔案中讀取的位置。

1
2
3
4
5
struct Student {
int studyNumber;
char name[80];
double score;
};
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
#include <stdio.h> 
#include "Student.h"

int main(int argc, char* argv[]) {
if(argc != 2) {
puts("指令: create <filename>");
return 1;
}

FILE *file = fopen(argv[1], "wb");

if(!file) {
puts("檔案輸出失敗");
return 1;
}

int count;
printf("要建立幾筆資料? ");
scanf("%d", &count);

struct Student student = {0, "", 0.0};
int i;
for(i = 0; i < count; i++) {
fwrite((char*) &student, sizeof(student), 1, file);
}

fclose(file);

return 0;
}
1
2
要建立幾筆資料? 
10

接下來可以使用下面這個程式進行隨機存取,使用學號來作資料的位置指定,將之儲存在檔案中的指定位置。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include <stdio.h> 
#include "Student.h"

int main(int argc, char* argv[]) {
struct Student student;
int count = 0;

if(argc < 2) {
puts("指令: write <filename>");
return 1;
}

FILE *file = fopen(argv[1], "r+b");
if(!file) {
puts("無法讀取檔案");
return 1;
}

while(1) {
fread((char*) &student, sizeof(student), 1, file);
if(!feof(file)) {
count++;
}
else {
break;
}
}

rewind(file);

printf("輸入學號(1-%d)\n", count);
puts("輸入0離開");

while(1) {
printf("\n學號? ");
scanf("%d", &(student.studyNumber));
if(student.studyNumber == 0) {
break;
}

printf("輸入姓名 分數\n? ");
scanf("%s %lf", student.name, &(student.score));

fseek(file, (student.studyNumber - 1) * sizeof(student), SEEK_SET);
fwrite((char*) &student, sizeof(student), 1, file);
}

fclose(file);

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
輸入學號(1-10)
輸入0離開

學號? 1
輸入姓名 分數
JJ
00

學號? 2
輸入姓名 分數
KK
0

學號? 8
輸入姓名 分數
LL
9

學號? 0

接下來可以使用下面這個程式讀取方才所輸入的資料。

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
#include <stdio.h> 
#include "Student.h"

int main(int argc, char* argv[]) {
struct Student student;
int count = 0, number;

if(argc != 2) {
puts("指令: read <filename>");
return 1;
}

FILE *file = fopen(argv[1], "r");
if(!file) {
puts("無法讀取檔案");
return 1;
}

while(1) {
fread((char*) &student, sizeof(student), 1, file);
if(!feof(file)) {
count++;
}
else {
break;
}
}
rewind(file);

printf("輸入學號(1-%d)\n", count);
puts("輸入0離開");

while(1) {
printf("\n學號? ");
scanf("%d", &number);
if(number == 0) {
break;
}
else if(number > count) {
printf("輸入學號(1-%d)\n", count);
continue;
}

puts("\n學號\t姓名\t\t分數");

fseek(file, (number - 1) * sizeof(student), SEEK_SET);
fread((char*) &student, sizeof(student), 1, file);
printf("%d\t%s\t%f\n",
student.studyNumber, student.name, student.score);
}

fclose(file);

return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
輸入學號(1-10)
輸入0離開

學號? 1

學號 姓名 分數
1 JJ 100.000000

學號? 2

學號 姓名 分數
2 KK 60.000000

學號? 8

學號 姓名 分數
8 LL 39.000000

學號? 3

學號 姓名 分數
0 0.000000

學號? 0


註:以上參考了
隨機存取檔案