文章目录
1、为什么使用文件
当我们写类似通讯录这样的代码时,就需要去录入信息,然而当程序结束的时候就会导致数据清除。下一次在运行程序·时候就需要再次写入数据,这样就显得很麻烦,为了把数据保存下来就需要使用文件。
使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。
2、什么是文件
磁盘上的文件是文件
在程序设计中,我们一般说的文件有两种:程序文件和数据文件
2.1、程序文件
包括源程序(后缀为.c),目标文件(windows环境后缀为.obj),可执行程序(后缀为.exe)
2.2、数据文件
文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。
2.3、拓展
以前我们学习的,处理数据的输入输出都是以终端为对象的,即从终端的键盘输入数据,运行结果显示到显示器上。
但是我们也可以把信息输出到磁盘上,当需要的时候再从磁盘上把数据读到内存中使用,这里处理的就是磁盘上的文件。
3、文件的打开和关闭
3.1、文件指针
一般我们使用都是通过文件指针,定义pf是一个指向FILE类型数据的指针变量。可以使pf指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说,通过文件指针变量能够找到与它关联的文件。
FILE* pf
3.2、文件的打开和关闭
1、fopen函数
2、fclose函数
例:
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main()
{
FILE* pf = fopen("date.text", "w");
if (pf == NULL)
{
perror("fopen");
return;
}
fclose(pf);
pf = NULL;
return 0;
}
如果使用“w”的方式,就会发现原来没有date.text这个文件,就会创造一个这个文件
如果使用“w”的方式,就会发现原来没有date.text这个文件,就会创造一个这个文件
3.3.相对路径与绝对路径
相对路径(这里指的是上一级的上一级路径)
绝对路径
4、文件的顺序读写
4.1简单概念的了解
首先我们需要去了解一些基本的概念,什么叫输入,什么叫输出。
然后去了解一些流的概念
4.2顺序读写函数的详解
(1)fgetc和fputc函数
fputc函数
int main()
{
FILE* pf = fopen("date.text", "w");
if (pf == NULL)
{
perror("fopen");
return;
}
fputc('a', pf);
fputc('b', pf);
fputc('c', pf);
fputc('d', pf);
fclose(pf);
pf = NULL;
return 0;
}
fgetc函数
int main()
{
FILE* pf = fopen("date.text", "r");
if (pf == NULL)
{
perror("fopen");
return;
}
int ch = fgetc(pf);
printf("%c", ch);
ch = fgetc(pf);
printf("%c", ch);
pf = NULL;
return 0;
}
(2)fgets和fputs函数
fputs函数
int main()
{
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
perror("fopen");
return 1;
}
//写文件
char ch = 0;
for (ch = 'a'; ch <= 'z'; ch++)
{
if (ch % 5 == 0)
fputc('\n', pf);
fputc(ch, pf);
}
fclose(pf);
pf = NULL;
return 0;
}
int main()
{
fputs("hello", stdout);//stdout是我们前面提到过打印到屏幕上的流
return 0;
}
还可以存到数组中去输出
fgets函数
(3)fscanf函数和fprintf函数
(4)fread和fwrite函数
这里你会发现二进制的文件打开,我们肉眼看不懂只能去借助fread函数,让计算机去读,通过验证,我们发现我们两个函数都是实现成功的
4.3对比函数
5、文件的随机读写
5.1 fseek函数
5.2 ftell函数
告诉你现在偏移了几个
5.3 rewind函数
6、文本文件和二进制文件
7、文件读取结束的判定
7.1 文件的读取的判定
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int c; // 注意:int,非char,要求处理EOF
FILE* fp = fopen("test.txt", "r");
if(!fp) {
perror("File opening failed");
return EXIT_FAILURE;
}
//fgetc 当读取失败的时候或者遇到文件结束的时候,都会返回EOF
while ((c = fgetc(fp)) != EOF) // 标准C I/O读取文件循环
{
putchar(c);
}
//判断是什么原因结束的
if (ferror(fp))//如果是在读取过程发生错误,会返回一个非零的正数
puts("I/O error when reading");
else if (feof(fp))
puts("End of file reached successfully");
fclose(fp);
}
7.2、文件的复制
#define _CRT_SECURE_NO_WARNINGS 1
//文件的复制
//实现将一个文件里的内容复制到另一个文件中
#include <stdio.h>
int main()
{
FILE* freadpf = fopen("date1.txt", "r");
if (freadpf == NULL)
{
perror("fopen1");
return;
}
FILE* fwritepf = fopen("date2.txt", "w");
if (fwritepf == NULL)
{
perror("fopen");
fclose(freadpf);
freadpf = NULL;
return;
}
//实现复制
int ch = 0;
while ((ch = fgetc(freadpf)) != EOF)
{
fputc(ch,fwritepf);
}
fclose(fwritepf);
fwritepf = NULL;
fclose(freadpf);
freadpf = NULL;
}
8、文件的缓冲区
ANSIC 标准采用“缓冲文件系统”处理的数据文件的,所谓缓冲文件系统是指系统自动地在内存中为程序
中每一个正在使用的文件开辟一块“文件缓冲区”。从内存向磁盘输出数据会先送到内存中的缓冲区,装
满缓冲区后才一起送到磁盘上。如果从磁盘向计算机读入数据,则从磁盘文件中读取数据输入到内存缓
冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(程序变量等)。缓冲区的大小根
据C编译系统决定的。
下面有段代码可以验证一下:
#include <stdio.h>
#include <windows.h>
//VS202 WIN11环境测试
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;
}