Like Share Discussion Bookmark Smile

J.J. Huang   2019-12-06   C C 語言技術 <201910>   瀏覽次數:次   DMCA.com Protection Status

C語言 - 第三十九章 | 檔案 I/O - 資料流游標

資料流游標

開啟檔案時,會有個游標指向檔案現在的讀取位置,每進行一次讀寫動作,游標會自動往下一個讀取位置前進,可以使用rewind()函式將游標重置回檔案開頭,或者是使用fseek()函式來移動游標。

1
int fseek(FILE *fp, long offset, int mode);

offset是相對於mode位置的位移量,可以是正或負數,正數表示往檔案相對於mode的下幾筆移動,負數表示往檔案相對於mode的上幾筆移動,mode是巨集定義的數值,可以設置的mode巨集名稱如下:

  • SEEK_SET:數值0,檔案開頭。
  • SEEK_CUR:數值1,目前游標所在位置。
  • SEEK_END:數值2,檔案結尾。

要進行非循序的檔案存取,通常會使用二進位模式,並且將資料以一定大小的資料結構包裝起來,下一個主題就會看到,但操作游標對循序性的檔案也有其好處,例如可以在文字檔案中儲存學生的資料並進行查詢,查詢的動作並不一定經過一次,所以可在每次查詢後,將游標移至檔案首,以便再次查詢。

1
2
3
4
5
6
7
8
9
10
1       Justin  90 
2 Momor 90
3 Bush 75
4 John 50
5 Bob 65
6 Rich 53
7 Doe 41
8 Bill 85
9 Jason 67
10 Jones 88
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> 

int main(int argc, char* argv[]) {
FILE *file = fopen("data.txt", "r");

if(!file) {
puts("無法讀取檔案");
return 1;
}

char name[30];
int request, account, score;

puts("輸入選項:");
puts("1) 顯示所有學生與分數");
puts("2) 顯示及格學生與分數");
puts("3) 顯示不及格學生與分數");
puts("4) 離開");

while(1) {
printf("\n選項? ");
scanf("%d", &request);
if(request == 4) {
break;
}

switch(request) {
case 1:
puts("\n所有學生與分數:");
break;
case 2:
puts("\n及格學生與分數:");
break;
case 3:
puts("\n不及格學生與分數:");
break;
}

fscanf(file, "%d\t%s\t%d", &account, name, &score);
while(!feof(file)) {
if((request == 1) || (request == 2 && score >= 60) ||
(request == 3 && score < 60)) {
printf("%d\t%s\t%d\n", account, name, score);
}

fscanf(file, "%d\t%s\t%d", &account, name, &score);
}

rewind(file); // 重置游標,也可使用 fseek(file, 0, SEEK_SET);
}

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
// 執行結果
輸入選項:
1) 顯示所有學生與分數
2) 顯示及格學生與分數
3) 顯示不及格學生與分數
4) 離開

選項? 1

所有學生與分數:
1 Justin 90
2 Momor 90
3 Bush 75
4 John 50
5 Bob 65
6 Rich 53
7 Doe 41
8 Bill 85
9 Jason 67
10 Jones 88

選項? 2

及格學生與分數:
1 Justin 90
2 Momor 90
3 Bush 75
5 Bob 65
8 Bill 85
9 Jason 67
10 Jones 88

選項? 3

不及格學生與分數:
4 John 50
6 Rich 53
7 Doe 41

選項? 4

為何文字檔案不適合非循序存取,理由很簡單,文字檔案的內容都經過字元轉換,假設現在有個檔案中有兩筆資料如下,其中空白為 '\t'

1
2
1       Justin  90 
2 Momor 90

如果現在更改了第一筆資料如下。

1
1       caterpillar  90

則第二筆資料會被覆蓋,如果是在Linux下,換行為'\n',則結果會如下。

1
1       caterpillar  90or   90

由於字元轉換後的資料長度並不固定,所以文字檔案並不適合非循序存取。


註:以上參考了
資料流游標