①文件的分类
操作系统是以文件为单位对数据进行管理的。
从用户观点:
1.特殊文件(标准输入输出文件或标准设备文件)
2.普通文件(磁盘文件)
从操作系统的角度看,每一个与主机相连的输入、输出设备看作是一个文件
按数据的组织形式:
ASCII文件(文本文件):每一个字节放一个ASCII代码
二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。
ASCII文件和二进制文件的比较:
ASCII文件便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间。
二进制文件可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。
一般中间结果数据需要暂时保存在外存上,以后又需要输入内存的,常用二进制文件保存。
C语言对文件的处理方法
1.缓冲文件系统:系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。用缓冲文件系统进行的输入输出又称为高级磁盘输入输出。
2.非缓冲文件系统:系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。用非缓冲文件系统进行的输入输出又称为低级输入输出系统。
C语言对文件的读写都是用库函数来实现的。
②文件的打开与关闭
文件型指针变量:FILE *fp;
fp是一个指向FILE类型结构体的指针变量。
我们使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。
1.文件的打开(fopen函数)
函数调用:FILE *fp;
fp=fopen(文件名,使用文件方式);
注意:
需要打开的文件名,也就是准备访问的文件的名字
使用文件的方式(“读”还是“写”等);
让哪一个指针变量指向被打开的文件。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
if(!(fp=fopen("E:\\fishc.txt","rb")))
{
printf("Can not open E:\\fishc file!\n");
system("pause");
}
else
{
printf("Open success!\n");
}
}
2.文件的关闭(fclose函数)
函数调用:
fclose(文件指针);
函数功能:使文件指针变量不指向该文件,也就是文件指针变量与文件“脱钩”,此后不能再通过该指针对原来与其相联系的文件进行读写操作。
返回值:
关闭成功返回值为0;否则返回EOF(-1)
文件的读写
对文件的读和写是最常用的文件操作。在C语言中提供了多种文件读写的函数:
字符读写函数:fgetc和fputc
字符串读写函数:fgets和fputs
数据块读写函数:freed和fwrite
格式化读写函数:fscanf和fprinf
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char ch,filename[20];
printf("please input the filename you want to write:");
scanf("%s",&filename);
if(!(fp=fopen(filename,"wt+")))
{
printf("Cannot open the file!\n");
exit(0);
}
printf("please input sentences you want to write:");
ch=getchar();
ch=getchar();
while(ch!=EOF)
{
fputc(ch,fp);
ch=getchar();
}
fclose(fp);
}
在fgetc()函数调用: ch=fgetc(fp);
其意义是从打开的文件fp中读取一个字符并送入ch中。
在文件内部有一个位置指针。用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc函数后,该位置指针将向后移动一个字节。因此可连续多次使用fgetc函数,读取多个字符。
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char ch,filename[20];
printf("please input the filename you want to write:");
scanf("%s",&filename);
if(!(fp=fopen(filename,"r")))
{
printf("Cannot open the file!\n");
exit(0);
}
while(ch!=EOF)
{
ch=fgetc(fp);
putchar(ch);
}
fclose(fp);
}
注意:
从一个文本文件顺序读入字符并在屏幕上显示出来:
ch=fgetc(fp);
while(ch!=EOF)
{
ch=fgetc(fp);
putchar(ch);
}
EOF不是可输出字符,不能在屏幕上显示。由于字符的ASCII码不可能出现-1,因此EOF定义为-1是合适的。当读入的字符值等于-1时,表示读入的已不是正常的字符而是文件结束符。
从一个二进制文件顺序读入字符:
while(!feof(fp)) { ch=fgerc(fp); }
ANSI C提供一个feof()函数来判断文件是否真的结束。如果是文件结束,函数feof(fp)的值为1(真);否则为0(假),以上也使用于文本文件的读取。
大家一起来写文件图片合成器吧~
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *f_pic,*f_file,*f_finish;
char pic_name[20],file_name[20],finish_name[20];
char ch;
printf("请输入需要合成的图片和文件的名称:\n");
printf("图片:");
scanf("%s",&pic_name);
printf("文件:");
scanf("%s",&file_name);
printf("生产为:");
scanf("%s",&finish_name);
if(!(f_pic=fopen(pic_name,"rb")))
{
printf("Cannot open the picture %s !",pic_name);
exit(0);
}
if(!(f_file=fopen(file_name,"rb")))
{
printf("Cannot open the file %s!",file_name);
return 0;//exit(0);
}
if(!(f_finish=fopen(finish_name,"wb")))
{
printf("Cannot open the finishi %s!",finish_name);
exit(0);
}
while(!(feof(f_pic)))
{
ch=fgetc(f_pic);
fputc(ch,f_finish);
}
fclose(f_pic);
while(!(feof(f_file)))
{
ch=fgetc(f_file);
fputc(ch,f_finish);
}
fclose(f_file);
fclose(f_finish);
system("pause");
}
字符串输入输出函数(fputs()和fgets())
函数作用:从fp所指的文件中读出n-1个字符送入字符数组str中,因为在最后加一个‘\0’.
#include<stdio.h>
#include<stdlib.h>
#define LEN 11
int main()
{
FILE *fp;
char butter[LEN];
if(!(fp=fopen("yangshuai.txt","rt")))
{
printf("Cannot open file ");
exit(1);
}
fgets(butter,LEN,fp);
printf("%s",butter);
fclose(fp);
}
注意,下面这个文本写入
#include<stdio.h>
#include<stdlib.h>
#define LEN 100
int main()
{
FILE *fp;
char ch,buffer[LEN];
if(!(fp=fopen("ys.txt","at+")))
{
printf("\nCannot open file strike any key exit!");
exit(1);
}
printf("please you want write:\n");
fgets(buffer,LEN,stdin);//stdin 是从键盘获取的文本信息
//为什么不用scanf(),因为scanf()函数面对空格就输入完成了
fputs(buffer,fp);
rewind(fp);//重新定义文件内部指针去到开头处
ch=fgetc(fp);
while(ch!=EOF)
{
putchar(ch);
ch=fgetc(fp);
}
printf("\n");
fclose(fp);
return 0;
}
数据块读写函数(fread()和fwrite())
函数调用:fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer:是一个指针;
对fread来说,它是读入数据的存放地址。
对fwrite来说,是要输出数据的地址(均指起始地址)。
size:要读写的字节数。
count:要进行读写多少个size字节的数据项。
fp:文件型指针。
从键盘输入4个学生的有关数据,然后把它们以二进制的格式存储到磁盘文件中。
#include<stdio.h>
#include<stdlib.h>
#define SIZE 4
struct student
{
char name[10];
int num ;
int age;
char addr[15];
} stu[SIZE];
void save()
{
FILE *fp;
int i;
if(!(fp=fopen("student-list","wb")))
{
printf("Cannot open the file!\n");
return ;
}
for (i=0;i<SIZE;i++)
{
if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
{
printf("File write error!\n");
fclose(fp);
}
}
}
void load();
int main()
{
int i;
printf("Please input the student's name,num,age and address:\n");
for(i=0;i<SIZE ;i++)
{
scanf("%s %d %d %s",&stu[i].name,&stu[i].num,&stu[i].age,&stu[i].addr);
}
save();
load();
printf(" name num age address\n\n");
for(i=0;i<SIZE;i++)
{
printf("%10s %5d %5d %10s\n",stu[i].name,stu[i].num,stu[i].age,stu[i].addr);
}
}
void load()
{
FILE *fp;
int i;
if(!(fp= fopen("student-list","r")))
{
printf("Cannot open the file!\n");
return ;
}
for(i=0;i<SIZE;i++)
{
fread(&stu[i],sizeof(struct student),1,fp);
}
fclose(fp);
}
随机读写
fseek函数(一般用于二进制文件)
函数功能:改变文件的位置指针
函数调用形式:fseek(文件类型指针,位移量,起始点)
起始点:
文件开头 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2
#include<stdio.h>
#include<stdlib.h>
struct student
{
char name[10];
int num ;
int age;
char addr[15];
} boy;
int main()
{
FILE *fp;
int i;// 用于定位第i 个结构
if(!(fp=fopen("student_list","r")))
{
printf("Cannot open the file!\n");
exit(0);
}
rewind(fp);
fseek(fp,i*sizeof(struct student),0);
fread(&boy,sizeof(struct student),1,fp);
printf("name\tnumber\t\tage\t\taddr\n");
printf("%s\t%5d %7d\t%s\n",boy.name,boy.num,boy.age,boy.addr);
system("pause");
}