| 第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);
          }
 
 |