C语言文件进阶操作

Description
文件a.dic、b.dic、c.dic中分别存有张三的三科成绩,每个文件都是16字节:前8个字节存储其英文名字zhangsan,后面是一个空格,其后的2个字节存储其年龄(文本方式存储)
,后面也是一个空格,最后4个字节存储的是某科考试成绩(二进制方式存储)。键盘输入一个数字(1,2,3),根据输入的数字从相应的文件中读出张三的数据并显示。

数字和文件的对应关系是:

1----a.dic

2----b.dic

3----c.dic

Input
输入1、2、3中的一个
Output
输出张三的数据,每项一行
Sample Input
1
Sample Output
zhangsan
18
96
Code 1 here:

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int main()
 4 {
 5     FILE *fp;
 6     char name[9];
 7     int n,age,score;
 8     scanf("%d",&n);
 9     if(n==1)
10         if((fp=fopen("C:\vc\a.dic","r"))==NULL)
11         {
12             printf("打开文件失败
");
13             exit(1);
14         }
15     if(n==2)
16         if((fp=fopen("C:\vc\b.dic","r"))==NULL)
17         {
18             printf("打开文件失败
");
19             exit(1);
20         }
21     if(n==3)
22         if((fp=fopen("c.dic","r"))==NULL)
23         {
24             printf("打开文件失败
");
25             exit(1);
26         }
27     fgets(name,9,fp);///读取n-1个字符
28     fscanf(fp,"%d",&age);///无视空格
29     fgetc(fp);///去掉空格
30     fread(&score,4,1,fp);///二进制方式读取
31     fclose(fp);///关闭文件
32     printf("%s
%d
%d
",name,age,score);
33     return 0;
34 }

Description
文件中存有3个人的姓名和数据(数据是不超过10000的整数),姓名是文本方式存储的,数据是二进制方式存储的,姓名和数据之间有一个空格,
当初这些数据是通过以下代码写进去的:
fp=fopen(filename,"wb"); //filename是数组名,其中存有文件名
for(i=1;i<=3;i++)
{
scanf("%s",name);
scanf("%d",&score);
fprintf(fp,"%s ",name); //%s后面有一个空格
fwrite(&score,4,1,fp);

}

文件已在后台,键盘输入文件名,读出并显示文件中的数据

Input
输入文件名

Output
输出三个人的数据

Sample Input
sample.dic

Sample Output
zhang,1990
wang,9678
sun,789

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int main()
 4 {
 5     FILE *fp;
 6     int i,score;
 7     char filename[20],name[9];
 8     fp=fopen(gets(filename),"wb+");///取文件名的方法
 9     for(i=1; i<=3; i++)
10     {
11         scanf("%s",name);
12         scanf("%d",&score);
13         fprintf(fp,"%s ",name///%s后面有一个空格
14         fwrite(&score,4,1,fp);
15     }
16     rewind(fp);///读写转换
17     for(i=1; i<=3; i++)
18     {
19         fscanf(fp,"%s",name);
20         fgetc(fp);///名字与成绩之间有空格需要fgetc取走或者fseek(fp,1,1);
21         fread(&score,4,1,fp);
22         printf("%s,%d
",name,score);
23     }
24     return 0;
25 }

从键盘中输入学生的学号,姓名,班级,成绩到文件中,按照成绩高低排名,输出到显示器(每一个内容之间有两个空格)

文件中的内容
1 wkf 1 78
2 ygh 1 88
3 wl 1 99
4 tcm 1 98
1 liuxc 1 67

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 # define N 5///宏定义,可以用来设定有多少个学生的信息
 4 typedef struct student
 5 {
 6     unsigned num;
 7     char name[9];
 8     unsigned cla;
 9     int score;
10 } STU; ///结构体来存储一个人的各种信息
11 void input()
12 {
13     STU s;
14     FILE *fp;
15     int i;
16     fp=fopen("C:\vc\b.dic","w+");
17     if(fp==0)
18     {
19         printf("File Open Error!
");
20         exit(1);
21     }
22 
23     for(i=1; i<=N; i++)
24     {
25         scanf("%d%s%d%d",&s.num,s.name,&s.cla,&s.score);///输入班级和成绩
26         fprintf(fp,"%2d %-8s %d%3d
",s.num,s.name,s.cla,s.score);
27     }
28     fclose(fp);
29 }///向文件中输入
30 void output()
31 {
32     STU s[N],t;///因为要排序,所以要使用数组
33     FILE *fp;
34     int i,j,k;
35     fp=fopen("C:\vc\b.dic","r+");
36     if(fp==0)
37     {
38         printf("File Open Error!
");
39         exit(1);
40     }
41     for(i=0; i<=N-1; i++)
42     {
43         fscanf(fp,"%d",&s [i].num);
44         fseek(fp,2,1);///要跳出name之后的两个空格
45         fgets(s[i].name,9,fp);///使用fgets的原因是为了防止名字中出现空格
46         fscanf(fp,"%d%d",&s[i].cla,&s[i].score);
47 
48     }
49     fclose(fp);
50     for(i=0; i<=N-2; i++) ///选择法排序
51     {
52         k=i;
53         for(j=i+1; j<=N-1; j++)
54             if(s[j].score>s[k].score)
55                 k=j;
56         t=s[i];
57         s[i]=s[k];
58         s[k]=t;
59     }
60     for(i=0; i<=N-1; i++)
61         printf("%d  %s  %d  %d
",s[i].num,s[i].name,s[i].cla,s[i].score);
62 }
63 int main()
64 {
65     input();
66     output();
67     return 0;
68 }

Description
用二进制方式打开文件并向文件中写了若干人的数据,每人的数据都有两项:其一是名字,是用文本方式写的,
其二是薪金(整数),是用二进制方式写的,名字后面和薪金后面各存有一个空格,每人都如此。除此之外文件中再无其他内容
即:文件中数据的存储顺序是名字 薪金 名字 薪金 名字 薪金......名字 薪金
文件已存在,键盘输入文件名,按顺序读出并显示所有人的数据。
说明:

1、所有人的名字中都不含空格,即:没有诸如“Bill Gates” 之类的名字

2、最后一个人的薪金之后,也有一个空格

3、OJ平台不支持fseek()函数,程序中不能使用fseek(),但你可以利用“读数据时读写位置指针会自动移动”这一特点来移动指针

4、文件在当前目录中,打开文件时不需要考虑盘符和路径

提示:若需要一个文件来验证程序的运行结果,可自行编程建立一个
Input
输入文件名
Output
输出所有人的数据
Sample Input

a.dic
Sample Output

zhangsan,2000
lisi,8000

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int main()
 4 {
 5     FILE *fp;
 6     int score;
 7     char filename[20],name[9];
 8     fp=fopen(gets(filename),"rb");
 9     fscanf(fp,"%s",name);///读取名字
10     fgetc(fp);///取掉空格
11     fread(&score,4,1,fp);///二进制读成绩
12     while(!feof(fp))
13     {
14         printf("%s,%d
",name,score);
15         fscanf(fp,"%s",name);
16         fgetc(fp);
17         fread(&score,4,1,fp);
18     }
19     return 0;
20 }

Description
文件aaa.dic、bbb.dic都是数据库文件(都在当前目录中)。数据库文件的文件头是一种固定的结构,如下表所示

文件头结构的内容是二进制方式存储的,从键盘输入一个数字,打开相应的数据库文件,求该数据库文件总共有多少条记录、有多少个字段、

键盘输入数字与数据库文件的对应关系是:


1--------aaa.dic


2--------bbb.dic

Input
输入1或者2,代表要打开不同的文件

Output
输出三个整数,每个一行

Sample Input
1

Sample Output
10
5
29

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int main()
 4 {
 5     FILE *fp;
 6     int n,a,b,c,x;
 7     scanf("%d",&n);
 8     if(n==1)
 9         if((fp=fopen("aaa.dic","rb"))==NULL)
10         {
11             printf("打开文件失败
");
12             exit(1);
13         }
14     if(n==2)
15         if((fp=fopen("bbb.dic","rb"))==NULL)
16         {
17             printf("打开文件失败
");
18             exit(1);
19         }
20     fseek(fp,4,1);
21     fread(&a,4,1,fp);///记录数
22     fread(&b,2,1,fp);///文件头的总长度
23     x=(b-32-1)/32;///字段数,1为文件头结束标志
24     fread(&c,2,1,fp);///每条记录的长度
25     fclose(fp);
26     printf("%d
%d
%d
",a,x,c);
27     return 0;
28 }
 1 #include<stdio.h>//利用结构体将文件头中的所有信息都存储到一起
 2 #include <stdlib.h>
 3 struct HEAD
 4 {
 5     char file_type;
 6     char date[3];
 7     int rec_num;
 8     short head_size;
 9     short rec_size;
10 };
11 int main()
12 {
13     FILE *fp;
14     struct HEAD head;
15     int n;
16     scanf("%d",&n);
17     if(n==1)
18         fp=fopen("aaa.dic","r");
19     if(n==2)
20         fp=fopen("bbb.dic","r");
21     if(fp==NULL)
22     {
23         printf("打开文件失败
");
24         exit(1);
25     }
26     fread(&head,12,1,fp);
27     printf("%d
%d
%d
",head.rec_num,(head.head_size-32)/32,head.rec_size);
28     return 0;
29 
30 }


文件aaa.dic、bbb.dic都是数据库文件(都在当前目录中)。数据库文件的文件头是一种固定的结构,如下表所示

文件头结构的内容是二进制方式存储的。

从键盘输入一个数字,打开相应的数据库文件(1--aaa.dic,2--bbb.dic),已知数据库中肯定有math这个字段(字段名:math),编程求出以下信息:

1、字段长度(或字段宽度,即该字段的信息占几个字节);

2、字段的值有几位小数;

3、该字段的值在一条记录中所处的起始位置。

例如:设某数据库文件各字段的描述如下:

字段名
name
English
addr
age
computer
math 

字段类型
C(字符)
N(数值)
C
N
N

字段宽度
10
5
20
3
5

小数位数
2
0
2

起始位置
1
11
23
16
43
19

则一条完整记录总共48(1+10+5+20+3+5+4)字节。

(开头第0字节用来存储空格或者星号,若是空格,表示本记录未被删除,若是星号,表示本记录已被逻辑删除)

下面是一条记录的内容:

zhangsan 78.25 1982.0sdibt 92.10 (本行是记录内容,共48字节)

012345678901234567890123456789012345678901234567890 (本行为了方便计数,并非记录内容)

其中:name字段的值是zhangsan(后面有两个空格),English的值是78.25,age是19(前面有一个空格),math是82.0,addr是sdibt(后面15个空格),computer是92.10

上面的数据中,字段math的值(82.0)在本记录中的起始位置是19。任意一条记录都是从第19字节(开头算第0字节)开始存储math的数据的,占多少字节由字段宽度决定。

特别说明:在OJ上提交的代码中,不允许使用fseek函数。(提示:读数据也可以移动指针)

Input
输入1或者2,以决定打开哪个文件

Output
输出所求的三个数据,每个一行

Sample Input
1

Sample Output
5
2
14

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 int main()
 4 {
 5     FILE *fp;
 6     int n;
 7     char a,b,c,d;
 8     scanf("%d",&n);
 9     if(n==1)
10         if((fp=fopen("aaa.dic","rb"))==NULL)
11         {
12             printf("打开文件aaa.dic失败
");
13             exit(1);
14         }
15     if(n==2)
16         if((fp=fopen("bbb.dic","rb"))==NULL)
17         {
18             printf("打开文件bbb.dic失败
");
19             exit(1);
20         }
21     fseek(fp,32,1);
22     while(1)///使用一个字符一个字符比对的方法
23     {
24         a=fgetc(fp);
25         b=fgetc(fp);
26         c=fgetc(fp);
27         d=fgetc(fp);
28         if(a=='m'&&b=='a'&&c=='t'&&d=='h')
29             break;
30         else
31             fseek(fp,28,1);
32     }
33     fseek(fp,8,1);
34     /*fread(math,1,10,fp);///使用strcmp比对,不成功就跳到下一个字段
35     while(strcmp(math,"math")!=0)
36     {
37         fseek(fp,22,1);
38         fread(math,1,10,fp);
39     }*/
40     fread(&c,4,1,fp);///本字段在记录中的起始位置
41     fread(&a,1,1,fp);///字段宽度
42     fread(&b,1,1,fp);///小数位数
43     fclose(fp);
44     printf("%d
%d
%d
",a,b,c);
45     return 0;
46 }
 1 #include<stdio.h>///利用结构体
 2 #include <stdlib.h>
 3 #include<string.h>
 4 struct HEAD///文件头
 5 {
 6     char file_type;
 7     char date[3];
 8     int rec_num;
 9     short head_size;
10     short rec_size;
11 };
12 struct FIELD///字段
13 {
14     char name[10];///字段名
15     char empty_c;///
16     char type;///字段类型
17     int begin;///字段在记录中的起始位置
18     char width;///字段长度
19     char digit;///小数位数
20 };
21 int main()
22 {
23     FILE *fp;
24     struct HEAD head;
25     struct FIELD field;
26     int n,i,field_num;
27     scanf("%d",&n);
28     if(n==1)
29         fp=fopen("aaa.dic","r");
30     if(n==2)
31         fp=fopen("bbb.dic","r");
32     if(fp==NULL)
33     {
34         printf("打开文件失败
");
35         exit(1);
36     }
37     fread(&head,12,1,fp);///有效信息
38     field_num=(head.head_size-33)/32;///字段的个数
39     fseek(fp,32,0);
40     for(i=1; i<=field_num; i++)
41     {
42         fread(&field,18,1,fp);
43         if(strcmp(field.name,"math")==0)
44             break;
45         fseek(fp,14,1);
46     }
47     printf("%d
%d
%d
",field.width,field.digit,field.begin);
48     fclose(fp);
49     return 0;
50 }

Description
键盘输入一个数字以打开相应的数据库文件(1---aaa.dic,2---bbb.dic),已知数据库文件中肯定有name和math两个字段且math起始位置大于name起始位置,请输出文件中第0条记录的name和math两个字段的值。math保留一位小数。有关数据库文件头的结构,请参看3591题目中的描述。文件头之后,是数据部分,数据部分的结构如下(所有内容都是文本方式存储的):如:Input
输入1或者2

Output
输出所求,分数保留一位小数(不设最小宽度)
Sample Input
1
Sample Output
qianqi
97.0

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 int main()
 5 {
 6     FILE *fp;
 7     int n,i,a,b,c;
 8     float num;
 9     char name[11],math[11],t;
10     scanf("%d",&n);
11     if(n==1)
12         if((fp=fopen("aaa.dic","r"))==NULL)
13         {
14             printf("打开文件aaa.dic失败
");
15             exit(1);
16         }
17     if(n==2)
18         if((fp=fopen("bbb.dic","r"))==NULL)
19         {
20             printf("打开文件bbb.dic失败
");
21             exit(1);
22         }
23     fseek(fp,8,0);
24     fread(&a,2,1,fp);///文件头的总长度
25     fseek(fp,32,0);
26     fread(name,1,10,fp);///字段名
27     while(strcmp(name,"name")!=0)///直到读到name字段
28     {
29         fseek(fp,22,1);
30         fread(name,1,10,fp);
31     }
32     fseek(fp,2,1);
33     fread(&b,4,1,fp);///name字段在每条记录中的起始位置
34     fread(&c,1,1,fp);///name字段的宽度
35     fseek(fp,a+b,0);///第一行name字段的位置
36     t=fgetc(fp);
37     for(i=1; t!=32&&i<=c; i++)
38     {
39         printf("%c",t);
40         t=fgetc(fp);
41     }
42     printf("
");
43     fseek(fp,32,0);
44     fread(math,1,10,fp);
45     while(strcmp(math,"math")!=0)
46     {
47         fseek(fp,22,1);
48         fread(math,1,10,fp);
49     }
50     fseek(fp,2,1);
51     fread(&b,4,1,fp);
52     fread(&c,1,1,fp);
53     fseek(fp,a+b,0);
54     fscanf(fp,"%f",&num);///此题使用fscanf有漏洞,因为math字段之后可能也储存着其他字段的数据,fscanf也会将其读出来,可能是因为保留一位小数的原因能够ac
55     printf("%.1f",num);///应该使用组装实数的方法,自己来推出fscanf函数的运算原理,分成小数点之前和之后两部分
56     return 0;
57 }
 1 #include<stdio.h>
 2 #include <stdlib.h>
 3 #include<string.h>
 4 struct HEAD///文件头
 5 {
 6     char file_type;
 7     char date[3];///最后修改的日期
 8     int rec_num;///记录数
 9     short head_size;///文件头的总长度
10     short rec_size;///每条记录的长度
11 };
12 struct FIELD///字段
13 {
14     char name[10];///字段名
15     char empty_c;///
16     char type;///字段类型
17     int begin;///字段在记录中的起始位置
18     char width;///字段长度
19     char digit;///小数位数
20 };
21 int main()
22 {
23     FILE *fp;
24     struct HEAD head;
25     struct FIELD field;
26     int n,i,field_num,len;
27     float num;
28     char t;
29     scanf("%d",&n);
30     if(n==1)
31         fp=fopen("aaa.dic","r");
32     if(n==2)
33         fp=fopen("bbb.dic","r");
34     if(fp==NULL)
35     {
36         printf("打开文件失败
");
37         exit(1);
38     }
39     fread(&head,12,1,fp);///有效信息
40     field_num=(head.head_size-33)/32;///字段的个数
41     fseek(fp,32,0);
42     for(i=1; i<=field_num; i++)
43     {
44         fread(&field,18,1,fp);
45         if(strcmp(field.name,"name")==0)
46             break;
47         fseek(fp,14,1);
48     }
49     len=head.head_size+field.begin;
50     fseek(fp,len,0);///跳到第0行name字段的位置
51     t=fgetc(fp);
52     for(i=1; t!=32&&i<=field.width; i++)
53     {
54         printf("%c",t);
55         t=fgetc(fp);
56     }
57     printf("
");
58     fseek(fp,32,0);
59     for(i=1; i<=field_num; i++)
60     {
61         fread(&field,18,1,fp);
62         if(strcmp(field.name,"math")==0)
63             break;
64         fseek(fp,14,1);
65     }
66     len=head.head_size+field.begin;
67     fseek(fp,len,0);///跳到第0行math字段的位置
68     fscanf(fp,"%f",&num);
69     printf("%.1f",num);
70     fclose(fp);
71     return 0;
72 }
原文地址:https://www.cnblogs.com/wkfvawl/p/9164416.html