【笔记】C语言的文件读写

前言

C语言的文件读写

引入头文件

1
#iinclude <stdio.h>

打开文件

  • 创建一个指针变量用于对文件操作,变量的数据类型为FILE

  • 如果打开文件成功,返回一个有效的内存地址;如果打开失败,返回值为NULL

  • 在Windows上

    • 如果处理文本文件,不要加b参数,让程序自动处理换行符\r\n
    • 如果处理二进制文件(不仅仅是写),要加b参数,不让程序自动处理换行符\r\n,手动写入数据时不添加无用的\r
  • 在Linux上,b参数是没有效果的,所以不用加b参数

<src>:文件的路径
<mode>:打开模式

参数 读写选项 是否为二进制 文件不存在是否报错 文件指针位置 备注
r 只读 报错 文件必须可读
r+ 读写 报错 文件必须可读
rb+ 读写 二进制 报错 只在Windows上有效,用来读取Windows上的换行符\r\n中的\r
rw+ 读写 报错 只在Windows上有效,用来读取Windows上的换行符\r\n中的\r
w 只写 新建文件 文件首部
wb 只写 二进制 新建文件 文件首部
w+ 读写 新建文件 文件首部
a 只写 新建文件 文件尾部 EOF符保留
a+ 读写 新建文件 文件尾部 EOF符不保留
1
2
3
4
int main()
{
FILE *p = fopen("<src>", "<mode>");
}

关闭文件

p:FILE类型的文件变量名

1
fclose(p);

读取一个字符

  • r模式打开
1
char c = getc(p);

终止符

  • 当读到最后一个字符的下一个字符时,会得到一个宏EOF,它的值是-1
  • EOF不是文件的一部分内容,只是文件结束的标识

通过判断终止符的方式遍历

通过break跳出无限循环
1
2
3
4
5
6
7
8
9
10
while(1)
{
char c = getc(p);
if (c==EOF)
{
break;
}

...
}
直接通过while的参数判断
1
2
3
4
5
6
7
char c = getc(p);
while(c != EOF)
{
...

c = getc(p);
}

写入一个字符

  • w模式打开

<char>:想要写入的字符
p:文件类型FILE变量

1
putc('<char>', p);

写入和读取字符串

写入字符串

<str>:字符串
p:文件指针变量

1
fputs("<str>", p);

读取字符串

1
fgets(buf, sizeof(buf), "<str>");

从控制台输入

1
fgets(buf, sizeof(buf), stdin);

判断文件指针是否为EOF文件结尾

p:文件指针

1
feof(p);

格式化读取和写入

格式化读取文件

p:文件指针

1
2
int a = 0;
fscanf(p, "%d", &a);

格式化写入文件

p:文件指针

1
2
int a = 0;
fprintf(p, "%d", a);

文件属性

引入头文件

1
2
3
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

创建一个结构体变量

1
struct stat st = { 0 };

获取文件的属性

  • 获取文件的属性,赋值给结构体变量

<file>:文件的路径
st:结构体变量

1
stat("<file>", &st);
  • 此时st结构体变量就存储了文件的所有属性

得到文件的大小

1
int size = st.st_size;

对二进制文件的写入和读取

写入数据到文件

&a:想要写入数据的内存地址
1:想要写入的单位数
sizeof(int):每个单位所占的内存大小
p:文件指针变量

1
2
int a = 0;
fwrite(&a, 1, sizeof(int), p);

读取文件中的数据

1
2
int a = 0;
fread(&a, 1, sizeof(int), p);

手动操作文件指针

移动文件指针

  • 默认情况下,文件指针是从头开始,每次自动向后移动
  • 如果想要手动操作文件指针,可以使用fseek函数

p:文件指针变量
<num>:指针从指针移动起始位置向左(-)或向右(+)移动的单位数
<location>:指针移动的起始位置

SEEK_SET:设置指针移动的起始位置为文件开头
SEEK_CUR:设置指针移动的起始位置为当前位置
SEEK_END:设置指针移动的起始位置为文件结尾

1
fseek(p, <step>, <num>);
  • 如果执行成功,返回0
  • 如果执行失败,返回非0,同时指针位置不改变
  • 如果超出最大位置,依然返回0,且此时再向前移动(不移动到文件内),依然返回0

快速生成一个大文件

1
2
3
4
5
6
7
8
9
main()
{
FILE *p = fopen("a.dat", "w");
fseek(p, 9999999, SEEK_SET);
char a = 0;
fwrite(&a, 1, sizeof(a), p);
fclose(p);
return 0;
}

查看文件指针的位置

p:文件指针变量

1
ftell(p);

得到文件的大小

1
2
3
4
5
6
main()
{
FILE *p = fopen("a.dat", "r");
fseek(p, 0, SEEK_END);
int size = ftell(p);
}

直接写入数据到文件

  • 在C语言写入数据到文件时,默认会先写入到缓冲区,目的是减少磁盘读写次数,从而延长磁盘使用寿命,提高效率
  • 当写入的数据超出缓冲区的大小,或者调用fclose函数,C语言程序就会立即将数据写入到磁盘
  • 如果想要不使用缓冲区,而是直接将数据写入磁盘,可以使用fflush函数
    • fflush函数可以立即将缓冲区内的数据写入到磁盘

p:文件指针变量

1
fflush(p);

对文件本身的操作

文件删除

<file>:文件名

1
remove("<file>");

文件重命名

<name_old>:改名前的文件名
<name_new>:改名后的文件名

1
rename("<name_old>", "<name_new>");

完成