主要内容
- 文件概述
- 文件指针
- 文件的打开与关闭
- 文件的读写
文件
把输入和输出的数据以文件的形式保存在计算机的外存储器上,可以确保数据能随时使用,避免反复输入和读取数据
文件概述
- 文件是指一组相关数据的有序集合
- 文件是存储数据的基本单位,可以通过读取文件访问数据。
分类
C语言文件分类
缓冲文件系统
非缓冲文件系统
文件输入输出函数
文件指针
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;
文件的打开与关闭
fopen函数
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);
}
fclose函数
文件的读写
fputc函数
【例13.1】从键盘输入文本,并将文本写入磁盘上存储的文本文件file_data.txt中。以字符#作为输入结束标志。
分析:
首先打开文件,然后从键盘循环输入字符,如果字符不是结束标志“#”,那么将字符写入文件,否则关闭文件
#include<stdio.h>
#include<stdlib.h>
void main()
{ FILE *fp;
char ch;
if( (fp = fopen("file_data.txt","w")) == NULL ) //打开文件
{ printf("can not open the file\n");
exit(0); //退出程序,必须包含<stdlib.h>头文件
}
ch = getchar();
while(ch != '#' )
{ fputc(ch,fp); //输出字符
ch = getchar();
}
fclose(fp); //关闭文件
}
fgetc函数
【例13.2】读取文本文件file_data.txt,并将文件中的内容输出到屏幕上。
分析:
首先打开文件,然后反复从文件中读入一个字符,并输出到屏幕,直到文件的结尾,最后关闭文件。
#include<stdio.h>
#include<stdlib.h>
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); //关闭文件
}
fputs函数
【例13.3】从键盘输入一串字符串,并将字符串写入文本文件file_data.txt中。
解决该问题的主要步骤为:
(1)打开文本文件file_data.txt。
(2)从键盘输入一串字符串。
(3)将字符串写入文件中。
(5)关闭文件。
(6)结束程序。
#include<stdio.h>
#include<stdlib.h>
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);
}
fgets函数
【例13.4】读取文本文件file_data.txt中指定长度的文本,长度由键盘输入,并将读取的内容输出到屏幕上。
解决该问题的主要步骤为:
(1)打开文本文件file_data.txt。
(2)从键盘输入要读取的文本长度。
(3)读入数据。
(4)输出数据。
(5)关闭文件。
(6)结束程序。
#include<stdio.h>
#include<stdlib.h>
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);
}
fprintf函数
【例13.5】将指定数据写入文本文件file_data.txt中。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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<stdio.h>
#include<stdlib.h>
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);
}
fscanf函数
【例13.7】以指定格式读取【例13.5】中生成的文件file_data.txt中的数据,并输出到屏幕上
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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);
}
fwrite函数
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<stdio.h>
#include<stdlib.h>
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);
}
因为是以二进制方式保存,所以记事本中的内容显示为乱码。
fread函数
【例13.9】将【例13.8】中已经存有book信息的文件打开,读出信息后显示在屏幕上。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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);
}
rewind函数
【例13.10】将指定字符串数据写入文本文件file_data.txt中,并将文件的位置指针重新定位到文件开头,读出文件中的第1个字符数据后显示在屏幕上。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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);
}
fseek函数
【例13.11】将指定字符串数据写入文本文件file_data.txt中,并将文件的位置指针定位到第5个字符之后,读出第6个字符并显示在屏幕上。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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);
}
ftell函数
【例13.12】求出文件中包含的字节数。
分析:
先将文件的位置指针移到文件末尾,再通过返回位置指针的位置来取得文件的字节数。
#include<stdio.h>
#include<stdlib.h>
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);
}
feof函数
【例13.13】判断文件指针是否在文本文件file_data.txt的末尾,并给出相应提示。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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);
}
ferror函数
【例13.14】判断的文本文件file_data.txt是否有错误,并给出相应提示。
编写程序如下:
#include<stdio.h>
#include<stdlib.h>
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);
}