前面介紹的文件讀寫函數都是順序讀寫,即讀寫文件只能從頭開始,依次讀寫各個數據。但在實際開發中經常需要讀寫文件的中間部分,要解決這個問題,就得先移動文件內部的位置指針,再進行讀寫。這種讀寫方式稱為隨機讀寫,也就是說從文件的任意位置開始讀寫。
實現隨機讀寫的關鍵是要按要求移動位置指針,這稱為文件的定位。
文件定位函數rewind和fseek
移動文件內部位置指針的函數主要有兩個,即 rewind() 和 fseek()。
rewind() 用來將位置指針移動到文件開頭,前面已經多次使用過,它的原型為:
void rewind ( FILE *fp );
fseek() 用來將位置指針移動到任意位置,它的原型為:
int fseek ( FILE *fp, long offset, int origin );
參數說明:
1) fp 為文件指針,也就是被移動的文件。
2) offset 為偏移量,也就是要移動的字節數。之所以為 long 類型,是希望移動的范圍更大,能處理的文件更大。
3) origin 為起始位置,也就是從何處開始計算偏移量。C語言規定的起始位置有三種,分別為文件開頭、當前位置和文件末尾,每個位置都用對應的常量來表示:
起始點 |
常量名 |
常量值 |
文件開頭
SEEK_SET
0
當前位置
SEEK_CUR
1
文件末尾
SEEK_END
2
例如,把位置指針移動到離文件開頭100個字節處:
fseek(fp, 100, 0);
值得說明的是,fseek() 一般用於二進制文件,在文本文件中由於要進行轉換,計算的位置有時會出錯。
文件的隨機讀寫
在移動位置指針之後,就可以用前面介紹的任何一種讀寫函數進行讀寫了。由於是二進制文件,因此常用 fread() 和 fwrite() 讀寫。
【示例】從鍵盤輸入三組學生信息,保存到文件中,然後讀取第二個學生的信息。
#include<stdio.h>
#define N 3
struct stu{
char name[10]; //姓名
int num; //學號
int age; //年齡
float score; //成績
}boys[N], boy, *pboys;
int main(){
FILE *fp;
int i;
pboys = boys;
if( (fp=fopen("d:\\demo.txt", "wb+")) == NULL ){
printf("Cannot open file, press any key to exit!\n");
getch();
exit(1);
}
printf("Input data:\n");
for(i=0; i<N; i++,pboys++){
scanf("%s %d %d %f", pboys->name, &pboys->num, &pboys->age, &pboys->score);
}
fwrite(boys, sizeof(struct stu), N, fp); //寫入三條學生信息
fseek(fp, sizeof(struct stu), SEEK_SET); //移動位置指針
fread(&boy, sizeof(struct stu), 1, fp); //讀取一條學生信息
printf("%s %d %d %f\n", boy.name, boy.num, boy.age, boy.score);
fclose(fp);
return 0;
}
運行結果:
Input data:
Tom 2 15 90.5↙
Hua 1 14 99↙
Zhao 10 16 95.5↙
Hua 1 14 99.000000