记录学习过程中的知识点
文章目录
一、文件
1.1 ASCII文件
在外存上以ASCII代码形式存储,则需要在存储前进行转换,称为文本文件,每一个字节存放一个字符的ASCII代码
1.2 二进制文件
数据是以二进制文件形式存储的,如果不加以转换输出到外存,就是二进制文件,可以认为它就是存储在内存的数据影响,也成为映像文件。
1.3 文件缓冲区
系统自动在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区
1.4 文件类型指针
每个被使用的文件都在内存中开辟一个相应的文件信息区,用来存放文件的有关信息,保存在一个结构体变量中
typedef struct
{
short level; //缓冲区“满”或“空”
unsigned flags; //文件状态标志
char fd; //文件描述符
unsigned char hold; //如缓冲区无内容不读取字符
short bsize; //缓冲区的大小
unsigned char * buffer; //数据缓冲区的位置
unsigned char * curp; //文件位置标记指针当前的指向
unsigned istemp; //临时文件指示器
short token; //用于有效检查
}FILE;
FILE类型变量定义:
FILE f1;
指向文件型数据的指针变量
FILE *fp;
通过文件指针变量能够找到与它关联的文件
1.5 文件尾标志EOF
EOF在stdio.h头文件中被定义为-1
二、打开与关闭文件
tips
- 文件的打开方式:
- 文本方式:不带b的方式,读写文件时对换行符进行转换
- 二进制方式:带b的方式,读写文件时对换行符不进行转换
- 文件读写函数:
- 文本读写函数:用来向文本文件读写字符数据的函数,如
fgetc,fgets,fputc,fputs,fscanf,fprintf
- 二进制读写函数:用来向二进制文件读写二进制数据的函数,如
getw,putw,fread,fwrite
2.1 fopen()
fopen(文件名,使用文件方式)
举例:
FILE *fp; //定义一个指向文件的指针变量fp
fp=fopen("a1","r"); //将fopen函数的返回值赋给指针变量fp
2.2 fclose()
fclose(fp);
如果不关闭文件就会结束程序运行,就会丢失数据
因为在向文件写数据时,待缓冲区充满之后才正式输出给文件
如果但数据为充满缓冲区就结束运行,就有可能使缓冲区中的数据丢失
用fclose函数关闭文件时,先把缓冲区中的数据输出到磁盘文件,然后才撤销文件信息区
fclose执行成功关闭,则返回0,否则返回EOF(-1)
三、顺序读写数据文件
3.1 向文件读写字符
3.1.1 fgetc()
fgetc(fp)
从fp指向的文件读入一个字符
读成功,带回所读字符,失败则返回文件结束符标志EOF(即-1)
fputc(ch,fp)
把字符ch写到文件指针变量fp所指的文件中
输出成功,返回值就是输出的字符,输出失败,则返回EOF(即-1)
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char ch,filename[10];
scanf("%s",filename);
getchar(); //消化回车符
if((fp=fopen(filename,"w"))==NULL)
{
printf("open failed\n");
exit(0);
}
printf("please input the str:\n");
ch = getchar();
while(ch!='#')
{
fputc(ch,fp);
putchar(ch);
ch=getchar();
}
fclose(fp);
putchar(10); //输出一个换行符
return 0;
}
3.2 向文件读写字符串
3.2.1 fgets()
函数原型
char *fgets(char *str,int n,FILE *fp);
调用形式
fgets(str,n,fp)
从fp指向的文件读入一个长度为(n-1)的字符串,存放到字符数组str中
n是要求得到的字符数与,但实际上只从fp所指向的文件中读入n-1个字符,然后再最后加上一个’\0’,如果在读完n-1个字符之前遇到换行符’\n’或者文件结束符EOF,读入即结束
读成功,返回地址str,失败返回NULL
3.2.2 fputs()
函数原型
int fputs(char *str, FILE *fp);
调用形式
fputs(str,fp)
把str所指的字符串输出到文件指针变量fp所指向的文件中
输出成功,返回0,否则返回非0
案例:对输入字符串进行排序并写入文件
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
FILE *fp;
char str[3][10],temp[10];
int i,j,k,n=3;
for(i=0;i<n;i++)
gets(str[i]);//输入字符串
for(i=0;i<n-1;i++)
{
k=il
for(j=i+1;j<n;j++)
if(strcmp(str[k],str[j]>0))
k=j;
if(k!=i)
{
strcpy(temp,str[i]);
strcpy(str[i],str[k]);
strcpy(str[k],temp);
}
}
if((fp=fopen("D:\\hello.txt"))==NULL)
{
printf("open error\n");
exit(0);
}
for(i=0;i<n;i++)
{
fputs(str[i],fp);
fputs("\n",fp);
}
return 0;
}
案例:从文件中读出字符串并显示在屏幕上
#include<stdio.h>
#include<stdlib.h>
int main()
{
FILE *fp;
char str[3][10];
int i=0;
if(fp=fopen("D:\\hello.txt","r")==NULL)
{
printf("open error\n");
exit(0);
}
while(fgets(str[i],10,fp)!=NULL)
{
printf("%s",str[i]);
i++;
}
fclose(fp);
return 0;
}
3.3 格式化读写文本文件
把变量格式化输出到文件
fprintf(文件指针,格式化字符串,输出表列);
举例:
fprintf(fp,"%d,%6.2f",a,b);
从文件格式化读入到变量
fscanf(文件指针,格式化字符串,输入表列);
举例:
fscanf(fp,"%d,%6.2f",&a,&b)
使用fprintf和fscanf对磁盘文件读写,使用方便,容易理解,但是在输入时要将文件中的ASCII码转换为二进制形式再保存在内存变量中;在输出时又要将内存中的二进制形式转换为字符,要花费较多时间。
3.4 二进制方式读写文本数据
fread(buffer,size,count,fp);
for(int i=0;i<40;i++)
fread(&stud[i].,sizeof(struct Student_type),1,fp);
fwrite(buffer,size,count,fp);
for(int i=0;i<40;i++)
fwrite(&stud[i].,sizeof(struct Student_type),1,fp);
执行成功返回值为count
- buffer:是操作的起始地址
- size:要写很多字节
- count:要写多少个数据项,每个 数据项长度为size
- fp:FILE类型指针
fread和fwrite函数用于二进制文件的输入输出,按照数据块长度处理,不出现字符转换
3.5 随机读写数据文件
可以根据读写的需要,认为移动文件位置标记的位置
3.5.1 rewind()
使文件位置标记重新定位于文件开头,同时feof函数的值会恢复为0(假)
3.5.2 fseek()
fseek(文件类型指针,位移量,起始点)
3.5.3 ftell()
测定文件位置标记的当前位置
i=ftell(fp)
案例:从文件中读入奇数序号的结构体变量
for(int i=0;i<10;i+=2)
{
fseek(fp,i*sizeof(struct Student_type),0);
fread(&stud[i],sizeof(struct Student_type),1,fp);
}
3.6 文件读写的出错检测
3.6.1 ferror()
返回非零值,表示出错
ferror(fp)
对同一个文件每一次调用输入输出函数都会产生一个新的ferror函数值,因此要在调用后立即检查ferror()的值
执行fopen函数是,ferror函数初始值自动置为0
3.6.2 clearerr()
使文件出错标志和文件结束标志置为0
假设在调用一个输入输出函数时出现错误,ferror函数值为一个非零值,应当立即调用clearerr(fp)
,使得ferror(fp)的值变为0,以便下一次检测。