c语言中关于文件的操作
一.c语言中关于文件一些总体认识:
1. 两种指针
- 文件指针:
- 指向:整个文件
- 定义:如FILE *fp;(FILE为文件类型)
- 获得:在使用打开文件函数打开文件时,该函数会返回一个文件指针
- 使用:在对文件进行操作时,是用该文件的文件指针表示该文件,进而进行操作
- 文件内部的位置指针:
- 指向:文件内部当前读写位置
- 定义:不需要定义,系统自动设定
- 获得:不需要获得
- 使用: 进行文件读写时,该指针指向当前读写位置,当读写完成后,自动后移。
- 区别:
文件指针和文件内部指针两种是完全不同的指针,两着区别很多,指向不同,文件指针需要定义,是可见的,一次赋值后,在后面的对文件的操作中,值是不变的。文件内部的位置指针,不需要定义,不可见,在对每文件进行一次读写后,该指针移动一次
2. 两种类型
- ascii文件
- 数据的存储:无论什么类型都以字符形式(ascii)存储
- 作用:二进制文件可以使用记事本等文件进行操作
- 二进制文件
- 数据的存储:以数据在内存中的二进制形式存储
- 作用:不能显示出来,用来暂存程序的中间结果
- 优点:由于已二进制读取,所以相比ASCII文件,二进制文件占用空间小,读取速度快。
3. 三步操作
- 第一步:打开(新建)文件(fopen)
- 第二步:对文件进行操作(读或写)
- 第三步:关闭文件(fclose)
4. 三种打开模式
- 对文件的打开操作有:读(r),写(w),追加(a)
- 打开类型:文本类型(t),二进制类型(b)
- 其他:读和写(+)
- 组合方式:显写打开操作,在写打开类型,+放最后(例:wt+)
- 写和追加的区别:写是将原文件的数据全部销毁,从头开始重写入,追加:是在文件末尾添加数据,不销毁原数据。
二.打开文件和关闭文件
1. 打开文件
- 函数原型:FILE *fopen(charc *filename,char *mode);
- 参数及返回值:filename:文件路径,mode:文件打开模式,返回值:打开成功后返回指向该文件的文件指针,失败返回NULL。
- 例
- fp=fopen(“e:\\code\\test.txt”,”rt”);以只读方式打开路径为e:/code/est.txt的文件
- fp=fopen(“e:/code/test.txt”,”wt”);以只写方式打开路径e:/code/test.txt文件
- fb=fopen(“test.txt”,at);已追加方式打开一个和c同目录下test.xt文件
- 打开文件需要提供的三个信息
- 需要打开文件的路径和名称(同目录下可以省略路径)
- 打开模式
- 将哪个指针遍变量指向打开的文件
2. 关闭文件
- 函数原型:int fclose(FILE *fb)
- 功能:关闭文件fp所指向的文件关闭,若返回0表示关闭成功,若返回非0表示关闭失败
- 例:fclose(fp);
三.使用函数进行文件的读写
读:从文件中读取数据。必须以读,读写形式打开文件
写:将数据写入文件。必须以写,读写,追加形式打开文件
fp:文件指针
流指针:文件内部位置指针
1. 单字符读写函数
- 函数原型:
- 读:int fgetc(FILE *fp);
- 写:int fputc(char ch,FILE *fp);
- 函数功能
- fgetc:读取fp所指向的文件中流指针所指向的字符.读取完毕(返回该字符),流指针自动移向下一个字符位置。若流指针移动到文件尾部,返回-1。
- fputc:把字符ch写入fp所指向的文件中流指针所指向的位置,写入完成后,流指针自动后移。写入成功后返回该字符ASCII值,失败返回EOF
- 函数使用示例
//读取fp所指向文件的的字符,直到文件结尾
while((ch=fgetc(fp)!=EOF) printf("%c",ch);
//将字符串str写入fp所指向的文件中
for(i=0;str[i];i++)
fputc(str[i],fp);
- 完整代码
#include <stdio.h>
int main(void)
{
FILE *fp;
char str[100],ch;
int i;
fp=fopen("temp.txt","wb");//以写的方式开文件 文件地址和c源文件同目录
if(fp==NULL)
{
printf("文件打开失败\n");
exit(0);
}
printf("请输入一个字符串:\n");
gets(str);
for(i=0;str[i];i++)//将字符串写入文件中
fputc(str[i],fp);
fclose(fp);//关闭文件,使流指针回到初始位置
fp=fopen("temp.txt","rb");//以读的方式打开文件
printf("文件内容为:\n");
while((ch=fgetc(fp))!=EOF)
printf("%c",ch);
printf("\n");
fclose(fp);//关闭文件
}
2. 字符串读写函数
- 函数原型
- char *fgets(char *str,int n,FILE *fp);
- int fputs(char *str,FILE *fp);
- 函数功能
- fgets:读取fp所指向的文件中流指针所指向的当前位置后n个字符放入str字符数组中,流指针移动n个位置。读取不到字符串时返回NULL。
- gets:将字符串str写入fp所指向的文件中,流指针所指向的当前位置。流指针后移n个位置。写入成功返回非0值,失败返回EOF。
- 函数使用示例
//从fp所指向文件位置读取10个字符存入str中。注意移动到文件末尾返回值不是EOF,是NULL
while((fgets(str,10,fp)!=NULL)printf("%s",str);
//将str字符串写入文件中。
fputs(str,fp);
- 完整代码
#include <stdio.h>
int main(void)
{
FILE *fp;
char str[100],ch;
fp=fopen("d:\\temp.txt","wb+");//以读写的方式开文件 ,位置:d盘目录下
if(fp==NULL)
{
printf("文件打开失败\n");
exit(0);
}
printf("请输入一个字符串:\n");
gets(str);
fputs(str,fp); //将字符串写入
fclose(fp);//关闭文件,使流指针回到初始位置
fp=fopen("d:\\temp.txt","r");
printf("文件内容为:\n");
while((fgets(str,10,fp))!=NULL)//读取文件中的数据
printf("%s",str);
printf("\n");
fclose(fp);
}
3. 格式化读写函数
- 函数原型
- int fscanf(FILE fp,”格式化字符串”,[输入项地址表]);
- int fprintf(FILE fp,”格式化字符串”,[输入项地址表]);
- 函数功能
- 读取fp所指向的文件中流指针所指向的当前位置,按格式化字符串指定格式将数据存入对于地址中。成功返回所读取数据的个数,流指针自动后移。失败返回EOF
- 将地址中的数据按照格式化字符串格式的格式写入到fp所指文件中,位置(流指所指向的位置)。同时流指针后移
- 函数使用示例
//将文件中的数据按照以空格为间隔,存入后面的各项内存空间中
fscanf(fp,"%s %s %s",num,name,sex);
//将后面各项地址所存的数据按照控格写入文件中
fprintf(fp,"%s %s %s",num,name,sex);
- 完整代码
#include <stdio.h>
int main(void)
{
FILE *fp;
char num[20],name[20],sex[20],filename[50];
printf("请输入文件地址及文件名:");
gets(filename);//文件地址可以由键盘录入
fp=fopen(filename,"wt+");//以读写的方式开文件
if(fp==NULL)
{
printf("文件打开失败\n");
exit(0);
}
printf("请输入学号:\n");
gets(num);
printf("请输入姓名:\n");
gets(name);
printf("请输入性别:\n");
gets(sex);
fprintf(fp,"%s %s %s\n",num,name,sex); //将数据写入
fclose(fp);//关闭文件,使流指针回到初始位置
fp=fopen(filename,"r");
printf("文件内容为:\n");
while((fscanf(fp,"%s %s %s",num,name,sex))!=EOF)//读取文件中的数据
printf("%s %s %s",num,name,sex);
printf("\n");
fclose(fp);
}
4. 数据块读写函数
- 函数原型
- int fread(void *buffer,int size,int count,FILE *fp);
- int fwrite(void *buffer,int size,int count,FILE *fp)
- 函数功能
- 读取fp所指向的文件中流指针所指向的位置,一次读取size个字节,重复count次。并将数据存入到buffer所指向的内存 空间中。同时流指针后移
- 从bufferz所指向的内存区开始,一次输入size个字节,重复count次。同时流指针后移
- 函数使用事例
//从fp所指的文件里,每次读取4个字节,读取5次,存入到fa数组中
float fa[5];
fread(fa,4,5,fp);
//从fa实行
fwrite(fa,4,5,fp);
- 完整代码
include <stdio.h>
int main(void)
{
FILE *fp;
char filename[100];
float fa[5],fb[5];
int i;
printf("请输入文件地址及文件名:");
gets(filename);//文件地址可以由键盘录入
fp=fopen(filename,"wt+");//以读写的方式开文件
if(fp==NULL)
{
printf("文件打开失败\n");
exit(0);
}
printf("请输入5个实数:\n");
for(i=0;i<5;i++)
scanf("%f",&fa[i]);
fwrite(fa,4,5,fp); //写入数据
fclose(fp);//关闭文件,使流指针回到初始位置
fp=fopen(filename,"r");
printf("文件内容为:\n");
fread(fb,4,5,fp);//读出数据
for(i=0;i<5;i++)
printf("%f ",fb[i]);
printf("\n");
fclose(fp);
}
四.其他关于文件操作的函数
1. 获得文件属性函数
- 函数原型:int fileno(FILE *fp);
- 功能:返回fp所指向文件的描述字。(当打开文件时,系统会赋予该文件一个号码,该号码用来代表所打开的文件。这个号码就是文件,描述字)
2. 获得文件大小函数
- 函数原型:long filelength(int handle_no)
- 功能:返回文件描述字所对应的文件大小,以字节为单位。
3. 移动流指针使它移向文件首部
- 函数原型:void rewind(FILE *fp);
- 功能:将流指针移动到文件开始的位置
4. 流指针移动函数
- 函数原型:int fseek(FILE *fp,long off,int whence);
- 功能:将fp所指文件内部流指针从 whence移向offset。
5. 获得流指针当前位置函数
- 函数原型:int ftell(FILE *fp);
- 功能:返回流指针当前位置,当出错时返回-1L;
6. 判断流指针是否处于文件结尾函数
- 函数原型:int feof(FILE *fp);
- 功能:判断fp所指文件中流指针是否位于末尾。是返回1,否返回0
7. 检查数据输入输出是否出错函数
- 函数原型:int ferror(FILE *fp);
- 功能:检查在文件操作时,有没有出错。未出错返回0,出错返回1.
8. 综合应用
#include <stdio.h>
#include <stdlib.h>
#include <io.h>
struct student
{
char num[20];
char name[20];
char sex[20];
}stu;
int main(void)
{
FILE *fp;
char filename[50];
int i,w,fno;
printf("请输入文件地址及文件名:");
gets(filename);//文件地址可以由键盘录入
fp=fopen(filename,"wt+");//以读写的方式开文件
if(fp==NULL)
{
printf("文件打开失败\n");
exit(0);
}
for(i=0;i<3;i++)//输入3条语句进入文件中
{
printf("请输入学号:\n");
gets(stu.num);
printf("请输入姓名:\n");
gets(stu.name);
printf("请输入性别:\n");
gets(stu.sex);
fprintf(fp,"%s %s %s\n",stu.num,stu.name,stu.sex); //将数据写入
}
if(!ferror(fp))//检查输入输出是否出错函数
printf("文件写入成功!\n");
else
printf("文件写入失败!\n");
rewind(fp);//是流指针移向开头
printf("文件内容为:\n");
while(!feof(fp))//检查流指针是否位于文件末尾
{
fscanf(fp,"%s %s %s",stu.num,stu.name,stu.sex);//读取文件中的数据
printf("%s %s %s\n",stu.num,stu.name,stu.sex);
}
fno=fileno(fp);
printf("该文件大小为:%d\n",filelength(fno));
fclose(fp);
}