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); }
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'
。
如果現在更改了第一筆資料如下。
則第二筆資料會被覆蓋,如果是在Linux
下,換行為'\n'
,則結果會如下。
由於字元轉換後的資料長度並不固定,所以文字檔案並不適合非循序存取。
註:以上參考了
資料流游標