第9章:文件 【例9-1】 将字符A、B、C和EOF写入A盘根目录下的文件ex9–1.txtdat中。
- #include <stdio.h>
- FILE *fi;
- main()
- { char a='A',b='B',c='C';
- if ((fi=fopen("a:\\ex9-1.txt","w"))==NULL)
- { printf("cannot open file\n"); exit(1); }
- fputc(a,fi);
- fputc(b,fi);
- fputc(c,fi);
- fputc(0xff,fi);
- fclose(fi);
- }
复制代码
【例9-2】 从例9-1建立的文件ex9-1.txt中读出所有的字符并显示在屏幕上。
- #include<stdio.h>
- FILE *fi;
- main()
- { char a;
- int i;
- if ((fi=fopen("a:\\ex9-1.txt","r"))==NULL)
- { printf("cannot open file\n"); exit(1); }
- ;
- while ((a=fgetc(fi))!=EOF)
- putchar(a);
- fclose(fi);
- }
复制代码
【例9-3】 将字符串"Turbo C","BASIC","FORTRUN","COBOL","PL-1"写入文件ex9-2.txt。
- #include <stdio.h>
- FILE *fi;
- main()
- { char a[][9]={"Turbo C","BASIC","FORTRAN","COBOL","PL-1"};
- int i;
- if ((fi=fopen("a:\\ex9-2.txt","w"))==NULL)
- { printf("Cannot open file\n");
- exit(1); }
- for (i=0;i<=4;i++)
- fputs(a[i],fi);
- fclose(fi);
- }
复制代码
【例9-4】在上例创建的ex9-2.txt文件的末尾追加3个字符串"C++"、"MS-C"和"Pascal"。
- #include <stdio.h>
- FILE *fi;
- main()
- { char a[][8]={"C++\n","MS-C\n","Pascal\n"};
- int i;
- if ((fi=fopen("a:\\ex9-2.txt","a"))==NULL)
- { printf("Cannot open file\n");
- exit(1); }
- for (i=0;i<=2;i++)
- fputs(a[i],fi);
- fclose(fi);
- }
复制代码
【例9-5】 从由例9-3和例9-4建立的文本文件ex9–2.txt中读出各个字符串并将其中第0、2、4、6号字符串显示在屏幕上。
- #include <stdio.h>
- FILE *fi;
- main()
- { char a[8][9];
- int i;
- if ((fi=fopen("a:\\ex9-2.txt","r"))==NULL)
- { printf("Cannot open file\n");
- exit(1); }
- for (i=0;i<=7;i++)
- { fgets(a[i],10,fi);
- if (i%2==0) /*从文件中读取字符串并 */
- printf("%s",a[i]); /* 显示第0、2、4、6号字符串 */
- }
- fclose(fi);
- }
复制代码
【例9-6】 将下表数据写入文件ex9-3.txt。 公司
| 类型
| 重量
| TOSHIBA
| J-3100SGT
|
6.8 kg
| NEC
| PC-9801LS
|
8.8 kg
| FUJITSU
| FMTOWNS
|
11.0 kg
| HITACHI
| B16X
|
7.3 kg
|
- #include <stdio.h>
- FILE *f;
- main()
- { char pc[][10]={"TOSHIBA","J-2100SGT","6.8kg","NEC","PC-9801LS",
- "8.8kg","FUJITSU","FMTOWNS","11.0kg"};
- int i;
- if ((f=fopen("a:\\ex9-3.txt","w"))==NULL)
- { printf("Cannot open file");
- exit(1); }
- for (i=0;i<=6;i+=3)
- fprintf(f,"%s %s %s ",pc[i],pc[i+1],pc[i+2]);
- fclose(f);
- }
复制代码
【例9-7】
读出例9-6所建立文件ex9-3.txt中的数据。
- #include <stdio.h>
- main()
- { FILE *f;
- char pc[9][10];
- int i;
- if ((f=fopen("a:\\ex9-3.txt","r"))==NULL)
- { printf("Cannot open file");
- exit(1); }
- for (i=0;i<=6;i+=3)
- fscanf(f,"%s%s%s",pc[i],pc[i+1],pc[i+2]);
- fclose(f);
- for (i=0;i<=6;i+=3)
- printf("FACT %10s TYPE %10s WEIG %7s\n",pc[i],pc[i+1],pc[i+2]);
- }
复制代码
程序输出结果如下:
FACT
TOSHIBA
TYPE
J-3100SGT WEIG
6.8 kg
FACT
NEC
TYPE
PC-9801LS WEIG
8.8 kg
FACT
FUJITSU
TYPE
FMTOWNS WEIG 11.0 kg
【例9-8】 从键盘输入100个整数,将它们存放在int型数组sam中,将该数组作为一个数据块写入文件ex9-4.dat中。 用“wb”方式打开文件,从键盘输入100个整数存放在数组sam中,然后用fwrite()将sam作为一个数据块写入文件ex9–4.dat。
- #include <stdio.h>
- #include <stdlib.h>
- FILE *fp;
- main()
- { int sam[100],i;
- if (!(fp=fopen("a:\\ex9-4.dat","wb")))
- { printf("Cannot open file\n");
- exit(1); }
- for (i=0;i<100;i++)
- scanf("%d",&sam[i]);
- fwrite(sam,sizeof(sam),1,fp);
- fclose(fp);
- }
复制代码
【例9-9】 从例9-8建立的二进制文件ex9-4.dat中读取10个浮点数存入数组b,并在屏幕上显示这10个数。 以“rb”方式打开文件,用fread()读入含10个整数的数据块存入数组b,再由printf()的格式控制将数组b中的二进制数转换成十进制数输出。
- #include <stdio.h>
- FILE *fp;
- main()
- { int b[10],i;
- if (!(fp=fopen("a:\\ex9-4.dat","rb")))
- { printf("Cannot open file\n");
- exit(1); }
- if (fread(b,sizeof(int),10,fp)!=10) /*读取的数据块不足*/
- { if (!feof(fp)) printf("premature end of file\n");
- /*已到文件末尾*/
- else printf("file read error\n"); /*读取过程中出错*/
- exit(1);
- }
- fclose(fp);
- for(i=0;i<10;i++)
- printf("%d",b[i]);
- }
复制代码
【例9-10】
文件拷贝。用命令行方式将一个二进制文件的内容拷贝到另一个文件中。命令行共3个参数,第一个参数为可执行程序名,第二、三个参数分别为需要拷贝的源文件和目的文件,它们将依次存放在argv[0]、argv[1]和argv[2]中。 用“rb”方式打开保存在argv[1]中的源文件名,用“wb”保存在argv[2]中的目的文件名,然后用fgetc()依次读出源文件中的每一个字符,用fputc()将该字符写入目的文件,这一过程直到feof()取非0值为止。程序如下:
- #include <stdio.h>
- FILE *in,*out;
- main(int argc,char *argv[])
- { char ch;
- if (argc!=3)
- { puts("You forget to enter a file name\n");
- exit(0); }
- if ((in=fopen(argv[1],"rb"))==NULL)
- { puts("Cannot open file\n");
- exit(0); }
- if ((out=fopen(argv[2],"wb"))==NULL)
- { puts("Cannot open file\n");
- exit(0); }
- while(!feof(in))
- { ch=fgetc(in); /*读取一个字节*/
- if (ferror(in)) /*读错*/
- { printf("read error\n");
- clearerr(in); /*清除出错标志*/
- exit(1);}
- else { fputc(ch,out); /*写入一个字节*/
- if (ferror(out)) /*写错*/
- { printf("write error\n");
- clearerr(out); /*清除出错标志*/
- exit(1); }
- }
- }
- fclose(in);fclose(out);
- }
复制代码
【例9-11】 利用ftell()和fseek()确定二进制文件的长度(字节数)和记录数。 假设一个二进制文件k.dat的每个记录含有若干字段,组织成一个struct st型数据,该文件用指针fp打开后,可以先用fseek()将文件指针定位到文件尾,用fteell()就可以获得该文件的长度,用文件长度与每个记录长度相除,就可以得到该文件所包含的记录数。
- FILE *fp;
- struct st
- { …… };
- int n,k;
- fp=fopen("k.dat","rb+");
- fseek(fp,0,SEEK_END); /*文件指针移到文件尾*/
- n=ftell(fp); /*文件长度字节数*/
- k=n/sizeof(struct st); /*文件记录数*/
复制代码
【例9-12】 建立一个考生档案顺序文件,包括准考证号、姓名、学校、数学、语文、外语、物理、化学、政治、生物和总分,并能根据准考证号进行顺序查询,通知该考生的考试成绩。 顺序文件是顺序存取的文件,它的各记录的长度既可以相等也可以不等,既可以是文本文件也可以是二进制文件。下面分别用文本文件和二进制文件的形式实现题目的要求。 (1) 在创建顺序文本文件时,最好配对使用文件读写函数,以保证输入或输出的格式一致。对只含文字数据的文本文件,可以配对使用fgetc()和fputc()、fgets()和fputs();对既有文字信息,又有数值信息的文本文件,通常配对使用fscanf()和fprintf()。下面的程序用来建立一个记录长度不等的顺序文本文件score.txt,每次循环写入一条记录。
- #include <stdio.h>
- FILE *fp;
- main()
- { int i,score[8];
- char num[8],name[11],school[11];
- if ((fp=fopen("a:\\score.txt","w"))==NULL)
- { printf("can not open file.\n");
- exit(1); }
- while(1) /* 输入考生信息 */
- { printf("input test number(0000000 to terminate):");
- gets(num);
- if (strcmp(num,"0000000")==0) break; /*输入0000000时结束*/
- printf("input name:");
- gets(name);
- printf("input school:");
- gets(school);
- printf("input Chinese:");
- scanf("%d",&score[0]);
- printf("input Mathematics:");
- scanf("%d",&score[1]);
- printf("input Foreign Language:");
- scanf("%d",&score[2]);
- printf("input Physics:");
- scanf("%d",&score[3]);
- printf("input Chemistry:");
- scanf("%d",&score[4]);
- printf("input Biology:");
- scanf("%d",&score[5]);
- printf("input Politics:");
- scanf("%d%*c",&score[6]);
- score[7]=0;
- for(i=0;i<7;i++) /* 计算总分 */
- score[7]+=score[i];
- fprintf(fp,"%s %s %s %d %d %d %d %d %d %d %d ",num,name,school,
- score[0],score[1],score[2],score[3],score[4],
- score[5],score[6],score[7]); /* 写入文件 */
- }
- fclose(fp);
- }
复制代码
【例9-13】 学生考试成绩登录程序。要求登录学号和分数两个信息,其中,学号也用做记录的编号。 用结构类型组织学生信息,包括学号和分数。输入时不必按学号的顺序进行,只要输入学号和分数,程序自动将该记录写到文件相应的位置上。在进行文件指针定位时,要使用fseek()函数,而fseek()函数在对文本文件定位时容易出错,因此随机文件通常是二进制文件。 下面是建立随机文件score1.dat的程序。程序自动将输入的学号num作为文件的记录号j:j=num-1(因为1号学生应处于第0号记录)。
- #include <stdio.h>
- FILE *fp;
- struct student
- { int num;
- int score; } st;
- main()
- { int j;
- if ((fp=fopen("a:\\score1.dat","wb"))==NULL)
- { printf("can not open file.\n");
- exit(1); }
- while(1)
- { printf("input number(0 to terminate):"); /* 输入学号 */
- scanf("%d",&st.num);
- if(st.num==0) break;
- printf("input score:"); /* 输入分数 */
- scanf("%d",&st.score);
- j=st.num-1; /* 计算记录号 */
- fseek(fp,(long)j*sizeof(st),0); /* 对第j号记录定位 */
- if(fwrite(&st,sizeof(struct student),1,fp)!=1) /*写入*/
- { puts("Write file error.\n");
- exit(1);
- }
- }
- fclose(fp);
- }
复制代码
|