把输入和输出的数据以文件的形式保存在计算机的外存储器上,可以确保数据能随时使用,避免反复输入和读取数据
(1)一种是“缓冲文件系统”
(2)一种是“非缓冲文件系统”
缓冲文件系统
非缓冲文件系统
文件指针
- typedef struct
- { int level; //缓冲区“满”或“空”的标志
- unsigned flags; //文件状态标志
- char fd; //文件描述
- unsigned char hold; //如果没有缓冲区则不读取字符
- int bsize; //缓冲区大小
- unsigned char _FAR *buffer; //缓冲区位置
- unsigned char _FAR *curp; //指向缓冲区当前数据的指针
- unsigned istemp; //临时文件指示器
- short token; //用于有效性检查
- }FILE;
文件的打开与关闭
FILE *fp;
//fp是一个指向FILE结构体类型的指针变量
fp = fopen("file_data.txt","r");
//以只读方式打开文件file_data.txt
fopen函数,会由于无法打开指定文件而出现错误。
如果出错,fopen函数会返回一个空指针值NULL(NULL在stdio.h中被定义为0)。
例如以“r”方式打开时,文件不存在,要进行错误处理。
FILE *fp;
if( (fp = fopen("file_data.txt","r") ) == NULL )
{ printf("can not open the file\n");
exit(0);
}
【例13.1】从键盘输入文本,并将文本写入磁盘上存储的文本文件file_data.txt中。以字符#作为输入结束标志。
分析:
首先打开文件,然后从键盘循环输入字符,如果字符不是结束标志“#”,那么将字符写入文件,否则关闭文件
- #include
- #include
- void main()
- { FILE *fp;
- char ch;
- if( (fp = fopen("file_data.txt","w")) == NULL ) //打开文件
- { printf("can not open the file\n");
- exit(0); //退出程序,必须包含
头文件 - }
- ch = getchar();
- while(ch != '#' )
- { fputc(ch,fp); //输出字符
- ch = getchar();
- }
- fclose(fp); //关闭文件
- }
【例13.2】读取文本文件file_data.txt,并将文件中的内容输出到屏幕上。
分析:
首先打开文件,然后反复从文件中读入一个字符,并输出到屏幕,直到文件的结尾,最后关闭文件。
- #include
- #include
- void main()
- { FILE *fp;
- char ch;
- if( (fp = fopen("file_data.txt","r")) == NULL ) //打开文件
- { printf("can not open the file\n");
- exit(0); //退出程序
- }
- ch = fgetc(fp); //从文件中读入一个字符
- while(ch != EOF )
- { putchar(ch);
- ch = fgetc(fp); //从文件中读入一个字符
- }
- fclose(fp); //关闭文件
- }
【例13.3】从键盘输入一串字符串,并将字符串写入文本文件file_data.txt中。
解决该问题的主要步骤为:
(1)打开文本文件file_data.txt。
(2)从键盘输入一串字符串。
(3)将字符串写入文件中。
(5)关闭文件。
(6)结束程序。
- #include
- #include
- void main()
- { FILE *fp;
- char str[20];
- if( (fp = fopen("file_data.txt","w")) == NULL )
- { printf("can not open the file\n");
- exit(0);
- }
- printf("input the string: ");
- gets(str);
- fputs(str,fp); //写入字符串
- fclose(fp);
- }
【例13.4】读取文本文件file_data.txt中指定长度的文本,长度由键盘输入,并将读取的内容输出到屏幕上。
解决该问题的主要步骤为:
(1)打开文本文件file_data.txt。
(2)从键盘输入要读取的文本长度。
(3)读入数据。
(4)输出数据。
(5)关闭文件。
(6)结束程序。
- #include
- #include
- void main()
- { FILE *fp;
- char str[20];
- int n;
- if( (fp = fopen("file_data.txt","r")) == NULL )
- { printf("can not open the file\n");
- exit(0);
- }
- printf("input the character's number: ");
- scanf("%d",&n);
- fgets(str,n+1,fp);
- printf("%s\n",str);
- fclose(fp);
- }
- 【例13.5】将指定数据写入文本文件file_data.txt中。
- 编写程序如下:
- #include
- #include
- void main()
- { FILE *fp;
- int i=10,j=12;
- double m=1.5,n=2.345;
- char s[]="this is a string";
- char c='\n';
- if( (fp = fopen("file_data.txt","w")) == NULL )
- { printf("can not open the file\n");
- exit(0);
- }
- fprintf(fp,"%s%c",s,c);
- fprintf(fp,"%d %d\n",i,j);
- fprintf(fp,"%lf %lf\n",m,n);
- fclose(fp);
- }
文件中保存的文本与程序中的数据一致,且格式与指定格式相同
- 【例13.6】按照每行5个数,将Fibonacci数列的前40个数写入file_data.txt文件中。
- 编写程序如下:
- #include
- #include
- void main()
- { FILE *fp;
- int f[40];
- int i;
- if( (fp = fopen("file_data.txt","w")) == NULL )
- { printf("can not open the file\n");
- exit(0);
- }
- for (i=0;i<=39;i++) //求Fibonacci数列
- { if (i==0||i==1)
- f[i]=1;
- else
- f[i]=f[i-2]+f[i-1];
- }
- for (i=0;i<=39;i++) //写入文件
- { if ((i+1)%5==0)
- fprintf(fp,"%10d\n",f[i]);
- else
- fprintf(fp,"%10d",f[i]);
- }
- fclose(fp);
- }
【例13.7】以指定格式读取【例13.5】中生成的文件file_data.txt中的数据,并输出到屏幕上
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { FILE *fp;
-
- int i,j;
-
- double m,n;
-
- char s1[100],s2[100],s3[100],s4[100];
-
- if( (fp = fopen("file_data.txt","r")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- fscanf(fp,"%s%s%s%s",s1,s2,s3,s4);
-
- //读入四个单词
-
- fscanf(fp,"%d%d",&i,&j);
-
- //读入两个整型数据
-
- fscanf(fp,"%lf%lf",&m,&n);
-
- //读入两个double类型数据
-
- printf("%s %s %s %s\n",s1,s2,s3,s4);
-
- printf("%d %d\n",i,j);
-
- printf("%lf %lf\n",m,n);
-
- fclose(fp);
-
- }
- struct Book_Type
- { char name[10];//书名
- int price;//价格
- char author[10];//作者名
- };
- for(i=0;i<2;i++)
- {
- fwrite(&book[i],sizeof(struct Book_Type),1,fp);
- }
【例13.8】通过键盘输入所有2本书的信息,并存储在文本文件file_data.txt中。
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { struct Book_Type
-
- { char name[10];//书名
-
- int price;//价格
-
- char author[10];//作者名
-
- };
-
- FILE *fp;
-
- struct Book_Type book[2];
-
- int i;
-
- if( (fp = fopen("file_data.txt","wb")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- printf("input the book info: \n");
-
- for(i=0;i<2;i++)
-
- { scanf("%s%d%s",book[i].name,&book[i].price,book[i].author);
-
- fwrite(&book[i],sizeof(struct Book_Type),1,fp);
-
- //读入一条记录
-
- }
-
- fclose(fp);
-
- }
因为是以二进制方式保存,所以记事本中的内容显示为乱码。
【例13.9】将【例13.8】中已经存有book信息的文件打开,读出信息后显示在屏幕上。
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { struct Book_Type
-
- { char name[10];//书名
-
- int price;//价格
-
- char author[10];//作者名
-
- };
-
- FILE *fp;
-
- struct Book_Type book[2];
-
- int i;
-
- if( (fp = fopen("file_data.txt","rb")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
-
- printf("the book info: \n");
-
- for(i=0;i<2;i++)
-
- fread(&book[i],sizeof(struct Book_Type),1,fp);
-
- for(i=0;i<2;i++)
-
- printf("name=%s,price=%d,author=%s\n",
-
- book[i].name,book[i].price,book[i].author);
-
- fclose(fp);
-
- }
【例13.10】将指定字符串数据写入文本文件file_data.txt中,并将文件的位置指针重新定位到文件开头,读出文件中的第1个字符数据后显示在屏幕上。
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { FILE *fp;
-
- char s[]="abcdefghijklmnopqrstuvwxyz";
-
- char c;
-
- if( (fp = fopen("file_data.txt","w+")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- fprintf(fp,"%s",s); //向文件中写入字符串
-
- rewind(fp); //指针返回开始
-
- fscanf(fp,"%c",&c); //读入一个字符
-
- printf("The first character is: %c\n",c);
-
- fclose(fp);
-
- }
【例13.11】将指定字符串数据写入文本文件file_data.txt中,并将文件的位置指针定位到第5个字符之后,读出第6个字符并显示在屏幕上。
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { FILE *fp;
-
- char s[]="abcdefghijklmnopqrstuvwxyz";
-
- char c;
-
- if( (fp = fopen("file_data.txt","w+")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- fprintf(fp,"%s",s);
-
- fseek(fp,5L,0);
-
- fscanf(fp,"%c",&c);
-
- printf("The first character is: %c\n",c);
-
- fclose(fp);
-
- }
【例13.12】求出文件中包含的字节数。
分析:
先将文件的位置指针移到文件末尾,再通过返回位置指针的位置来取得文件的字节数。
- #include
-
- #include
-
- void main()
-
- { FILE *fp;
-
- long l;
-
- if( (fp = fopen("file_data.txt","r")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- fseek(fp,0L,SEEK_END); //将文件的位置指针移到文件末尾
-
- l=ftell(fp); //返回位置指针的位置
-
- fclose(fp);
-
- printf("the length of file is %ld\n",l);
-
- }
【例13.13】判断文件指针是否在文本文件file_data.txt的末尾,并给出相应提示。
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { FILE *fp;
-
- char ch;
-
- if( (fp = fopen("file_data.txt","r")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- do
-
- { ch=fgetc(fp);
-
- putchar(ch);
-
- }while (!feof(fp)); //判断是否到达文件尾
-
- if(feof(fp)) printf("\nWe have reached end-of-file\n");
-
- //判断是否到达文件尾
-
- fclose(fp);
-
- }
【例13.14】判断的文本文件file_data.txt是否有错误,并给出相应提示。
编写程序如下:
- #include
-
- #include
-
- void main()
-
- { FILE *fp;
-
- if( (fp = fopen("file_data.txt","r")) == NULL )
-
- { printf("can not open the file\n");
-
- exit(0);
-
- }
-
- if(ferror(fp))
-
- printf("Error reading from file_data.txt\n");
-
- else
-
- printf("There is no error\n");
-
- fclose(fp);
-
- }