【C语言】文件操作详解
文章目录
- 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文件关闭的同时就被销毁了,它的内容并不能顺延到下一次打开这个通讯录,这对我们的使用产生了不便。
而文件可以帮助我们实现数据的持久化:将数据保存在磁盘文件中,下次打开通讯录的时候,之前保存的联系人不会消失。
2.什么是文件?
文件就是存放在磁盘上的带特定格式的数据。
2.1文件分类
在程序设计中,一般讨论两种文件:程序文件、数据文件
- 程序文件:代码源文件
如.c
,目标文件.obj/.o
,可执行文件.exe
- 数据文件:程序在使用过程中读写的数据,比如读取内容的文件,以及数据输出的文件
这篇博客我们了解的是数据文件
2.2文件名
文件名包含3个部分:文件路径+文件名主干+文件后缀
如:c:\code\test.txt
文件标识常被称为文件名
3.文件的使用
3.1文件指针
在文件操作中,非常重要的一个知识点就是文件类型指针
,简称文件指针
每个文件在开辟的时候都有一个对于的文件信息区,用于保存文件的名字、状态、当前的位置等相关信息。这些信息保存在了一个结构体中,该结构体系统声明为FILE
不同的C语言编译器都有不同的FILE类型,但是大同小异。
打开一个文件的时候,系统会根据文件的内容,自动创建FILE结构体变量,并填充它的信息。
我们需要使用文件的时候,就可以通过一个FILE类型的指针来访问这个结构体变量
3.2打开和关闭文件
文件在读写之前需要打开文件,使用结束后需要关闭文件
这一点和动态内存管理很相似
ANSIC规定用fopen函数来打开文件,fclose来关闭文件。
打开文件的同时,会返回一个FILE*
的指针变量指向该文件。
关闭文件后,文件指针就变成了野指针,需要置为NULL防止错误调用
fopen函数打开文件失败,会返回空指针
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;
}
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文件使用方式
通过这张表格,我们可以了解一下文件使用方式的不同类型
- 注意:使用它们用的都是双引号,而不是单引号!
用w写入的时候,会覆盖原本已有内容。如果需要在已有内容后面追加,需要使用a
3.2.2标准输入输出流
- 输出:内存→文件
- 输入:文件→内存
C语言程序,运行的时候会默认打开3个流
- stdin:标准输入流
- stdout:标准输出流
- stderr:标准错误流
在执行输入输出操作的时候,之前我们是直接将内存中的数据printf打印到屏幕上
现在我们可以通过文件指针,将数据输入到标准输出流,达到类似printf的效果
3.3文件输入输出函数
上述代码中,用到了fputc
函数,这个函数的作用是将一个字符输入到文件中
下表列出了一些我们会用到的文件函数
3.3.1字符输入输出
fputc函数:向文件中写入单个字符
fgetc函数:从文件中读取单个字符
可以看到,我们把刚刚文件中写入的字符全部打印出来了
实现文件拷贝
将一个文件的内容拷贝到另外一个文件中
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;
}
3.3.2文本行输入输出
fputs函数:将字符串写入到文件中
//写一行
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文件中
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个字符出来
将buf[2]
更改为1,调试查看
可以看到,在执行第一个fgets
函数后,原本的1被写入成了\0
这就证实:fgets函数在读取字符的时候,会以\0
作为结尾
如果我们需要读取3个字符,就需要将限制设置为4
3.3.3格式化输入输出
这里的“格式化”指的是结构体这种具有特定格式的数据内容
fprintf函数:将格式化数据写入文件中
//……
struct Stu
{
char name[20];
int age;
double d;
};
int main()
{
struct Stu s上一篇: C语言-文件操作
下一篇: c语言文件读写操作
推荐阅读
-
[C 语言教程] [嵌入式程序设计] (I) 简介和先决条件 (II) 嵌入式程序设计基础 (III) 硬件基础 (IV) 硬件寄存器操作
-
C# 文件操作
-
C 语言从零开始 68 - 学习头文件 string.h
-
C 文件操作(下) (28)
-
Linux 安装软件、GCC 编译器、Linux 操作系统基础 - 编译单个 c 文件
-
[C 语言]指针详解 (I)
-
什么是挂载,Linux挂载详解-纠正一个误区,并不是根目录下任何一个目录都可以作为挂载点,由于挂载操作会使得原有目录中文件被隐藏,因此根目录以及系统原有目录都不要作为挂载点,会造成系统异常甚至崩溃,挂载点最好是新建的空目录。
-
详解:使用C语言实现的猜数字小游戏
-
【C语言初阶篇】 while 语句的语法和注意事项 (详解版)
-
[C语言进阶篇] 结构体进阶详解:通过阅读这篇文章,我的数据结构能力有了显著提升!