前言:
我们为什么要在C语言中引进文件的概念呢?试想一个场景,我们写好了通讯录的源代码运行后录入了联系人的信息,但是每次的操作范围只局限在此次的执行程序中,执行程序一关,联系人的信息随着执行程序在内存中的消失而消失。因此,我们需要把联系人信息保存到硬盘上的话,就需要了文件操作,这就引入了文件。
目录
1、文件的分类
(1)程序文件
(2) 数据文件
2、文件的打开与关闭
(1)文件指针的介绍
(2)文件的打开与关闭
(3)文件的顺序读写
(4)文件的随机读写
(5)文件缓冲区
FILE* pf
通过以上学习对于如何找到文件我们知道了是通过文件指针找到要访问的文件内容。那么如何打开文件呢?这就要介绍下面两个操作文件的函数了:
//打开文件
FILE * fopen ( const char * filename, const char * mode );
//关闭文件
int fclose ( FILE * stream )
这里可见fopen的返回值类型是FILE*型,通常我们写成FILE* pf=FILE*( const char * filename, const char * mode ),用FILE*类型的pf指针接收并打开。
fopen的第一个输入对象是文件名,第二个则是打开类型,有如下的打开类型:
学到这里,我们就能掌握最基础的文件操作,打开关闭了,如例:
#include
int main ()
{
FILE * pFile;
//打开文件
pFile = fopen ("myfile.txt","w");
//文件操作
if (pFile!=NULL)
{
fputs ("fopen example",pFile);
//关闭文件
fclose (pFile);
}
return 0; }
通过以上的学习,我们下面应该学习如何用C语言读写文件内容。这里给出一些最基本的操作函数:
下面我给出各个函数使用实例:
#include
//int main()
//{
// FILE* pf = fopen("tets.txt", "w");
// if(pf==NULL)
// {
// perror("fopen");
// return 1;
// }
//
// //写文件
// int i = 0;
// for (i = 0; i < 26; i++)
// {
// fputc('a' + i, pf);
// }
// fclose(pf);
// pf = NULL;
// return 0;
//}
//int main()
//{
// FILE* pf = fopen("tets.txt", "r");
// if (pf == NULL)
// {
// perror("fopen");
// return 1;
// }
//
// //读文件
// /*int ch;
// while((ch=fgetc(pf))!=EOF)
// {
// printf("%c ", ch);
// }*/
//
//
// fclose(pf);
// pf = NULL;
// return 0;
//}
//
//int main()
//{
// FILE* pf = fopen("tets.txt", "w");
// if (pf == NULL)
// {
// perror("fopen");
// return 1;
// }
// fputs("hello", pf);
// fputs("bitejiuyeke", pf);
//
//
// fclose(pf);
// pf = NULL;
// return 0;
//}
//
//int main()
//{
// FILE* pf = fopen("tets.txt", "r");
// if (pf == NULL)
// {
// perror("fopen");
// return 1;
// }
// //读
// char arr[] = "***********";
// fgets(arr, 3, pf);//实际上只读两个,后面放个 \0
// //,每次只读一行
// printf("%s", arr);
//
// fclose(pf);
// pf = NULL;
// return 0;
//}
//结构体数据
struct S
{
char name[20];
int age;
float score;
};
//int main()
//{
// struct S s = { "zhangsan",20,95.5f };
// //写到文件中
// FILE* pf=fopen("test.txt","w");
// if(NULL==pf)
// {
// perror("fopen");
// return 1;
// }
// //写文件
// fprintf(pf, "%s %d %f", s.name, s.age, s.score);
//
//
// fclose(pf);
// pf = NULL;
//
//
// return 0;
//}
//
//int main()
//{
// struct S s = { "zhangsan",20,95.5f };
// //写到文件中
// FILE* pf = fopen("test.txt", "r");
// if (NULL == pf)
// {
// perror("fopen");
// return 1;
// }
// //读文件
// fscanf(pf, "%s %d %f", &(s.name),&( s.age), &(s.score));
// printf("%s %d %f\n", s.name, s.age, s.score);
// return 0;
//
//}
上面是文件的顺序读写,那么我们想要读写指定的文件内容该怎么办呢?下面我们介绍随机读写文件的一些函数:
1.fseek
int fseek(FILE* stream, long int offset, int origin);
第一对象是文件流,第二个是想要访问文件内容的偏移量,第三个是起始位置的描述(起始位置有三个,分别为:SEEK_SET文件起始,SEEK_CUR文件中间,SEEK_END文件末尾),例子如下:
//int main()
//{
// FILE* pf=fopen("test.txt", "r");
// if(pf==NULL)
// {
// perror("fopen");
// return 1;
// }
// //读文件
// int ch = fgetc(pf);
// printf("%c\n", ch);
//
// //SEEK_SET起始
// //SEEK_CUR中间
// //SEEK_END末尾
//
//
// /*fseek(pf, -3, SEEK_END);*/
// fseek(pf, 2, SEEK_CUR);
//
// ch = fgetc(pf);
// printf("%c\n", ch);
//}
2.retell
long int ftell ( FILE * stream );
返回的是当前文件指针所在文件流的位置。
3.rewind
void rewind ( FILE * stream );
retell,rewind我们借用fseek使用到的代码举例:
//int main()
//{
// FILE* pf=fopen("test.txt", "r");
// if(pf==NULL)
// {
// perror("fopen");
// return 1;
// }
// //读文件
// int ch = fgetc(pf);
// printf("%c\n", ch);
//
// //SEEK_SET起始
// //SEEK_CUR中间
// //SEEK_END末尾
//
//
// /*fseek(pf, -3, SEEK_END);*/
// fseek(pf, 2, SEEK_CUR);
//
// ch = fgetc(pf);
// printf("%c\n", ch);
//
// int pos = ftell(pf);
// printf("%d\n", pos);
ftell
返回文件指针相对于起始位置的偏移量
//
// rewind(pf);
// ch = fgetc(pf);
// printf("%c\n", ch);
//
rewind
让文件指针的位置回到文件的起始位置
// fclose(pf);
// pf = NULL;
// return 0;
//}
//
//
文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间。通过磁盘缓存来实现,磁盘缓存本身并不是一种实际存在的存储介质,它依托于固定磁盘,提供对主存储器存储空间的扩充,即利用主存中的存储空间, 来暂存从磁盘中读出(或写入)的信息。 主存也可以看做是辅存的高速缓存, 因为,辅存中的数据必须复制到主存方能使用;反之,数据也必须先存在主存中,才能输出到辅存。
#include
#include
//VS2013 WIN10环境测试
int main()
{
FILE*pf = fopen("test.txt", "w");
fputs("abcdef", pf);//先将代码放在输出缓冲区
printf("睡眠10秒-已经写数据了,打开test.txt文件,发现文件没有内容\n");
Sleep(10000);
printf("刷新缓冲区\n");
fflush(pf);//刷新缓冲区时,才将输出缓冲区的数据写到文件(磁盘)
//注:fflush 在高版本的VS上不能使用了
printf("再睡眠10秒-此时,再次打开test.txt文件,文件有内容了\n");
Sleep(10000);
fclose(pf);
//注:fclose在关闭文件的时候,也会刷新缓冲区
pf = NULL;
return 0; }
应用文件缓冲区可以很好地提高存储效率。比如,我去问老师问题,我发现一个去问一个,问十几个就要去十几次,但是如果我把问题聚在一起,一次去问十几个问题,老师的办公效率是不是会得到提升呢?