對流式文件可以進行順序讀寫,也可以進行隨機讀寫,關鍵在于控制文件的位置指針。如果位置指針是按字節位置順序移動的,就是順序讀寫;如果能將位置指針按需要移動到任意的位置,就可以實現隨機讀寫.所謂隨機讀寫,是指讀寫完上一個字符(字節)后,并不一定要讀寫其后續的字符(字節),而可以讀寫文件中任意位置上所需要的字符(字節)。
用 fseek 函數可以實現改變文件的位置指針。
fseek 函數的調用形式為: fseek (文件類型指針,位移量,起始點)
“起始點 ”用0、1或 2 代替,0代表 “文件開始”,1 為“當前位置”,2 為 “文件末尾”。 ANSI C 標準指定的名字如下表所示:
起始點 名字 用數字代表
文件開始 SEEK_SET 0
文件當前位置 SEEK_ CUR 1
文件末尾 SEEK_END 2
“位移量”指以 “起始點” 為基點,向前移動的字節數。ANSI C 和大多數版本要求位移量是(long)長整型數據。這樣當文件的長度大于64KB時不致出問題。ANSI C 標準規定在數字的末尾加一個字母 L,就表示是 long 型。
fseek 函數一般用于二進制文件,因為文本文件要發生字符轉換,計算位置時往往會發生混亂。
下面是fseek 函數調用的幾個例子:
fseek(fp,100L,0);/* 將位置指針移到離文件頭100個字節處 */
fseek(fp,50L,1); /* 將位置指針移到離當前位置50個字節處 */
fseek(fp,--10L,2);/* 將位置指針從文件末尾處向后退 10 個字節 */
利用 fseek 函數就可以實現隨機讀寫了。
例13.5 在磁盤文件上存有 10 個學生的數據。要求將第 1、3、5、7、9個學生數據輸入計算機,并在屏幕上顯示出來。程序如下:
#include "stdlib.h"
#include "stdio.h"
struct student_type
{
char name[10];
int num;
int age;
char sex;
}stud[10];
void main()
{
int a;
FILE * fp;
if((fp=fopen("stud_dat.txt","rb"))==NULL)
{
printf("can not open file\n");
exit(0);
}
for(a=0;a<10;a+=2)
{
fseek(fp,a * sizeof(struct student_type),0);
fread(&stud[a],sizeof(struct student_type),1,fp);
printf("%s %d %d %c\n",stud[a].name,stud[a].num,stud[a].age,stud[a].sex);
}
fclose(fp);
}
(先新建一個文本文件名為“stud_dat.txt”(可以改其它名字),然后在里面輸入10學生的數據。接著再把本程序在VC編譯系統中運行……)。
13.5.3 ftell 函數
ftell 函數的作用是得到流式文件中的當前位置,用相對文件開頭的位移量來表示。由于文件中的位置指針經常移動,人們往往不容易知道其當前位置。
用 ftell 函數可以得到當前位置 。如果 ftell 函數返回值為--1L,表示出錯。例如:
a=ftell(fp);
if(a==--1L)
printf("error\n");
變量 a 存放當前位置,如調用函數時出錯(如不存在 fp 文件),則輸出“error”。
tell(告訴,吩咐,斷定,知道,)
例13.4 有一個磁盤文件,第一次將它的內容顯示在屏幕上,第二次把它復制
#include "stdio.h"
void main()
{
FILE * fp1,* fp2;
fp1=fopen("file1.txt","r");
fp2=fopen("file2.txt","w");
while(! feof(fp1))
putchar(getc(fp1));
rewind(fp1);
while(! feof(fp1))
putc(getc(fp1),fp2);
fclose(fp1);
fclose(fp2);
}
例13.5 在磁盤文件上存有 10 個學生的數據。要求將第 1、3、5、7、9個學
#include "stdlib.h"
#include "stdio.h"
struct student_type
{
char name[10];
int num;
int age;
char sex;
}stud[10];
void main()
{
int a;
FILE * fp;
if((fp=fopen("stud_dat.txt","rb"))==NULL)
{
printf("can not open file\n");
exit(0);
}
for(a=0;a<10;a+=2)
{
fseek(fp,a * sizeof(struct student_type),0);
fread(&stud[a],sizeof(struct student_type),1,fp);
printf("%s %d %d %c\n",stud[a].name,stud[a].num,stud[a].age,stud[a].sex);
}
fclose(fp);
}
file1(文本文檔里的內容)
Nu11 pointer assignment
(無效的) ( 指示器)(分配、任務、作業)
stud_dat(文本文檔里的內容)
Nu11 pointer assignment
(無效的) ( 指示器)(分配、任務、作業)
Nu11 pointer assignment
(無效的) ( 指示器)(分配、任務、作業)
Nu11 pointer assignment
(無效的) ( 指示器)(分配、任務、作業)
Nu11 pointer assignment
(無效的) ( 指示器)(分配、任務、作業)
Nu11 pointer assignment
(無效的) ( 指示器)(分配、任務、作業)