欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

【C语言】文件操作详解

最编程 2024-08-13 09:24:31
...



文章目录

  • ​1.为什么需要文件?​
  • ​2.什么是文件?​
  • ​2.1文件分类​
  • ​2.2文件名​
  • ​3.文件的使用​
  • ​3.1文件指针​
  • ​3.2打开和关闭文件​
  • ​3.2.1文件使用方式​
  • ​3.2.2标准输入输出流​
  • ​3.3文件输入输出函数​
  • ​3.3.1字符输入输出​
  • ​实现文件拷贝​
  • ​3.3.2文本行输入输出​
  • ​3.3.3格式化输入输出​
  • ​3.3.4二进制输入输出​
  • ​3.3.5 sscanf/sprintf函数​
  • ​3.4.其他文件函数​
  • ​3.4.1 fseek​
  • ​3.4.2 ftell​
  • ​3.4.3 rewind​
  • ​4.文本文件和二进制文件​
  • ​5.文件读取结束的判定​
  • ​5.1错误使用feof​
  • ​6.文件缓冲区​
  • ​代码示例1​
  • ​代码示例2​
  • ​结语​


好久没有更新C语言学习的博客了,今天带来的是文件部分的知识点!????

1.为什么需要文件?

之前学习过通讯录的代码实现,可以给通讯录中增加、删除联系人。但是这个通讯录在你exe文件关闭的同时就被销毁了,它的内容并不能顺延到下一次打开这个通讯录,这对我们的使用产生了不便。

而文件可以帮助我们​实现数据的持久化​:将数据保存在磁盘文件中,下次打开通讯录的时候,之前保存的联系人不会消失。

【C语言】文件操作详解_c语言


2.什么是文件?

文件就是存放在磁盘上的带特定格式的数据。

2.1文件分类

在程序设计中,一般讨论两种文件:程序文件、数据文件

  • 程序文件:代码源文件​​如.c​​​,目标文件​​.obj/.o​​​,可执行文件​​.exe​
  • 数据文件:程序在使用过程中读写的数据,比如读取内容的文件,以及数据输出的文件

这篇博客我们了解的是​​数据文件​

2.2文件名

文件名包含3个部分:​​文件路径+文件名主干+文件后缀​

如:​​c:\code\test.txt​

文件标识常被称为文件名

3.文件的使用

3.1文件指针

在文件操作中,非常重要的一个知识点就是​​文件类型指针​​,简称文件指针

每个文件在开辟的时候都有一个对于的文件信息区,用于保存文件的名字、状态、当前的位置等相关信息。这些信息保存在了一个结构体中,该结构体系统声明为​FILE

不同的C语言编译器都有不同的FILE类型,但是大同小异。

打开一个文件的时候,系统会根据文件的内容,自动创建FILE结构体变量,并填充它的信息。

【C语言】文件操作详解_后端_02

我们需要使用文件的时候,​就可以通过一个FILE类型的指针来访问这个结构体变量

【C语言】文件操作详解_开发语言_03

3.2打开和关闭文件

文件在读写之前需要​打开文件​,使用结束后需要​关闭文件


这一点和动态内存管理很相似


ANSIC规定用fopen函数来打开文件,fclose来关闭文件。

打开文件的同时,会返回一个​​FILE*​​的指针变量指向该文件。


关闭文件后,文件指针就变成了​野指针​,需要置为NULL防止错误调用


fopen函数打开文件失败,会返回空指针

#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));//用该函数打印错误信息
return 0;
}
//1.读文件

//关闭文件
fclose(pf);
pf = NULL;
return 0;
}
#include <stdio.h>
#include <errno.h>
#include <string.h>
int main()
{
//打开文件
FILE* pf = fopen("test.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));//用该函数打印错误信息
return 0;
}
//2.写文件

//关闭文件
fclose(pf);
pf = NULL;

return 0;
}


strerror函数在这篇博客里面有讲解????​​点我​


3.2.1文件使用方式

通过这张表格,我们可以了解一下文件使用方式的不同类型

  • 注意:使用它们用的都是​双引号​,而不是单引号!

【C语言】文件操作详解_文件指针_04

用w写入的时候,​会覆盖原本已有内容​。如果需要在已有内容后面​追加​,需要使用a

【C语言】文件操作详解_c语言_05

3.2.2标准输入输出流

  • 输出:内存→文件
  • 输入:文件→内存

【C语言】文件操作详解_文件指针_06

C语言程序,运行的时候会默认打开3个流

  • stdin:标准输入流
  • stdout:标准输出流
  • stderr:标准错误流

在执行输入输出操作的时候,之前我们是直接​将内存中的数据printf打印到屏幕上

现在我们可以通过文件指针,将数据​输入到标准输出流​,达到类似printf的效果

【C语言】文件操作详解_开发语言_07

3.3文件输入输出函数

上述代码中,用到了​​fputc​​函数,这个函数的作用是将​一个字符输入到文件中

下表列出了一些我们会用到的文件函数

【C语言】文件操作详解_文件指针_08

3.3.1字符输入输出

fputc函数:向文件中写入单个字符

【C语言】文件操作详解_数据_09

fgetc函数:从文件中读取单个字符

可以看到,我们把刚刚文件中写入的字符全部打印出来了

【C语言】文件操作详解_数据_10

实现文件拷贝

将一个文件的内容拷贝到另外一个文件中

int main()
{
//实现一个代码将data.txt 拷贝一份 生成data2.txt
FILE* pr = fopen("data.txt", "r");
if (pr == NULL)
{
printf("open for reading: %s\n", strerror(errno));
return 0;
}

FILE* pw = fopen("data2.txt", "w");
if (pw == NULL)
{
printf("open for writting: %s\n", strerror(errno));
fclose(pr);
pr = NULL;
return 0;
}
//拷贝文件
int ch = 0;
while ((ch = fgetc(pr)) != EOF)
{
fputc(ch, pw);
}

fclose(pr);
pr = NULL;
fclose(pw);
pw = NULL;

return 0;
}

【C语言】文件操作详解_文件指针_11


3.3.2文本行输入输出

fputs函数:将字符串写入到文件中

//写一行
#include <stdio.h>
int main()
{
FILE* pf = fopen("data.txt", "w");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 0;
}
fputs("hello world\n", pf);
fputs("hehe\n", pf);


fclose(pf);
pf = NULL;

return 0;
}

运行代码,可以看到两行字符串已经被写入到了项目路径下的data.txt文件中

【C语言】文件操作详解_后端_12

fgets函数:从文件中读取规定长度的字符串

该函数在使用的时候具有第3个参数,用于限制读取字符串的长度

读文件-读一行
int main()
{
FILE* pf = fopen("data.txt", "r");
if (pf == NULL)
{
printf("%s\n", strerror(errno));
return 0;
}
char buf[1000] = {0};
//读文件
fgets(buf, 3, pf);
printf("%s\n", buf);

fgets(buf, 3, pf);
printf("%s\n", buf);

fclose(pf);
pf = NULL;

return 0;
}

运行程序,可以看到我们设置的是3,却只读取了2个字符出来

【C语言】文件操作详解_c语言_13

将​​buf[2]​​更改为1,调试查看

【C语言】文件操作详解_开发语言_14

可以看到,在执行第一个​​fgets​​​函数后,原本的1被写入成了​​\0​

【C语言】文件操作详解_数据_15

这就证实:fgets函数在读取字符的时候,会以​​\0​​作为结尾

如果我们需要读取3个字符,​就需要将限制设置为4


3.3.3格式化输入输出

这里的“格式化”指的是结构体这种​具有特定格式的数据内容

fprintf函数:将格式化数据写入文件中