Day Day Up—— ——fseek()函数的用法
在牛客网遇到的一个程序题中用到了函数fseek()故查阅了一下该函数的功能及用法,整理如下:
fseek函数功能是把文件指针指向文件的开头,需要包含头文件stdio.h
功 能: 重定位流上的文件指针
函数原型:int fseek( FILE *stream, long offset, int origin );
第一个参数stream为文件指针
第二个参数offset为偏移量,整数表示正向偏移,负数表示负向偏移
第三个参数origin设定从文件的哪里开始偏移,可能取值为:SEEK_CUR、 SEEK_END 或 SEEK_SET
SEEK_SET: 文件开头
SEEK_CUR: 当前位置
SEEK_END: 文件结尾
其中SEEK_SET,SEEK_CUR和SEEK_END和依次为0,1和2.
如:
fseek(fp,100L,0);把fp指针移动到离文件开头100字节处;
fseek(fp,100L,1);把fp指针移动到离文件当前位置100字节处;
fseek(fp,100L,2);把fp指针退回到离文件结尾100字节处。
返回值: 成功,返回0,否则返回其他值。
用法: int fseek(FILE *stream, long offset, int fromwhere);fseek 用于二进制方式打开的文件,移动文件读写指针位置.
fseek(in,-1L,1); -- 文件流in, 零点为当前指针位置,SEEK_CUR 就是 1, -1L -- 文件指针回退1个字节
程序示例:
Question:程序通过定义学生结构体变量,存储学生学号、姓名和三门课的成绩。所有学生数据均以二进制方式输出到student.dat文件中。函数fun的功能是:从文件中找出指定学号的学生数据,读入此学生数据,对该学生的分数进行修改,使每门课的分数加三分,修改后重写文件中学生的数据,即用是该学生的新数据覆盖原数据,其他学生数据指定不变;若找不到,则不做任何操作。
(这里的运行结果是给LiSi同学的每科加了3分)
1 #include<stdio.h> 2 3 #define N 5 4 5 typedef struct student { 6 long sno; 7 char name[10]; 8 float score[3]; 9 } STU; 10 11 void fun(const char *filename, long sno) 12 { 13 FILE *fp; 14 STU n; 15 int i; 16 fp = fopen(filename, "rb+"); 17 /**********found**********/ 18 while (!feof(fp)) { 19 fread(&n, sizeof(STU), 1, fp); 20 /**********found**********/ 21 if (n.sno == sno) 22 break; 23 } 24 if (!feof(fp)) { 25 for (i = 0; i < 3; i++) n.score[i] += 3; 26 /**********found**********/ 27 fseek( fp, -1L * sizeof(STU), SEEK_CUR); 28 fwrite(&n, sizeof(STU), 1, fp); 29 } 30 fclose(fp); 31 } 32 33 int main( ) 34 { 35 STU t[N] = { 36 {10001, "MaChao", 91, 92, 77}, 37 {10002, "CaoKai", 75, 60, 88}, 38 {10003, "LiSi", 85, 70, 78}, 39 {10004, "FangFang", 90, 82, 87}, 40 {10005, "ZhangSan", 95, 80, 88} 41 }, ss[N]; 42 int i, j; 43 FILE *fp; 44 fp = fopen("student.dat", "wb"); 45 fwrite(t, sizeof(STU), N, fp); 46 fclose(fp); 47 printf("\nThe original data :\n"); 48 fp = fopen("student.dat", "rb"); 49 fread(ss, sizeof(STU), N, fp); 50 fclose(fp); 51 for (j = 0; j < N; j++) { 52 printf("\nNo: %ld Name: %-8s Scores: ", ss[j].sno, ss[j].name); 53 for (i = 0; i < 3; i++) 54 printf("%6.2f ", ss[j].score[i]); 55 printf("\n"); 56 } 57 fun("student.dat", 10003); 58 fp = fopen("student.dat", "rb"); 59 fread(ss, sizeof(STU), N, fp); 60 fclose(fp); 61 printf("\nThe data after modifing :\n"); 62 for (j = 0; j < N; j++) { 63 printf("\nNo: %ld Name: %-8s Scores: ", ss[j].sno, ss[j].name); 64 for (i = 0; i < 3; i++) printf("%6.2f ", ss[j].score[i]); 65 printf("\n"); 66 } 67 return 0; 68 }
Output:
The original data : No: 10001 Name: MaChao Scores: 91.00 92.00 77.00 No: 10002 Name: CaoKai Scores: 75.00 60.00 88.00 No: 10003 Name: LiSi Scores: 85.00 70.00 78.00 No: 10004 Name: FangFang Scores: 90.00 82.00 87.00 No: 10005 Name: ZhangSan Scores: 95.00 80.00 88.00 The data after modifing : No: 10001 Name: MaChao Scores: 91.00 92.00 77.00 No: 10002 Name: CaoKai Scores: 75.00 60.00 88.00 No: 10003 Name: LiSi Scores: 88.00 73.00 81.00 No: 10004 Name: FangFang Scores: 90.00 82.00 87.00 No: 10005 Name: ZhangSan Scores: 95.00 80.00 88.00
补充:fopen与fclose
FILE *fopen(char *filename, *type);
fopen()函数中第一个形式参数表示文件名, 可以包含路径和文件名两部分。
a (append 追加) 若要向一个已存在的文件追加新的信息,只能用“a ”方式打开文件。
fopen函数用来打开一个文件,其调用的一般形式为:
文件指针名=fopen(文件名,使用文件方式)
其中,“文件指针名”必须是被说明为FILE 类型的指针变量,“文件名”是被打开文件的文件名。 “使用文件方式”是指文件的类型和操作要求。“文件名”是字符串常量或字符串数组。eg: FILE *fp;fp=("file a","r");(意义是在当前目录下打开文件file a, 只允许进行“读”操作,并使fp指向该文件)。
eg:FILE *fphzkfphzk=fopen("d:\\a","rb")其意义是打开d驱动器磁盘的根目录下的文件a, 这是一个二进制文件,只允许按二进制方式进行读操作。两个反斜线“\\ ”中的第一个表示转义字符,第二个表示根目录。
“rb” 只读打开一个二进制文件,只允许读数据。用了“b”参数就表示以二进制方式读写,故读写操作需要使用fread和fwrite函数
fclose()函数
fclose()函数用来关闭一个由fopen()函数打开的文件 , 其调用格式为:
int fclose(FILE *stream);
该函数返回一个整型数。当文件关闭成功时, 返回0, 否则返回一个非零值。可以根据函数的返回值判断文件是否关闭成功。
例子:
FILE *fpOut=fopen(“c:\\a.txt”,”w+”);
int a=1;
fprintf(fpOut,”%d”,a);
fclose(fpOut);
可参考文章:http://dwz.cn/2Ko4zA