首页 > 技术文章 > Day Day Up—— ——fseek()函数的用法

Miranda-lym 2016-02-17 21:30 原文

在牛客网遇到的一个程序题中用到了函数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_CURSEEK_END和依次为012.
如:

 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()函数中第一个形式参数表示文件名, 可以包含路径和文件名两部分。

返回值:文件顺利打开后,向该流的文件指针就会被返回。如果文件打开失败则返回NULL,并把错误代码存在errno中,在程序中可以用这一信息来判别是否完成打开文件的工作,并作相应的处理。
一般而言,打开文件后会做一些文件读取或写入的动作,若打开文件失败,接下来的读写动作也无法顺利进行,所以一般在fopen()后作错误判断及处理。
type有以下三种形态字符串:
r 以只读方式打开文件,该文件必须存在。
w 打开只写文件,若文件存在则文件长度清为0,即该文件内容会消失。若文件不存在则建立该文件。

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

http://dwz.cn/2JZ0p2

推荐阅读