【c语言】玩转文件操作

ephemerals__ 2024-07-21 09:05:02 阅读 95

🌟🌟作者主页:ephemerals__

🌟🌟所属专栏:C语言

目录

引言

一、文件的打开和关闭

1.流

2.标准流

3.文本文件和二进制文件

4.控制文件打开与关闭的函数

二、文件的顺序读写

三、文件的随机读写

1.fseek函数

2.ftell函数

3.rewind函数

四、文件读取结束的判定

总结


引言

        我们在写程序的时候,往往会将数据存放在变量当中。如果程序退出,内存回收,这些数据就会丢失。那么我们是否有办法对这些数据进行持久化的保存,再次打开程序时数据仍然存在?答案是肯定的。而能够做到这件事的就是:文件操作

一、文件的打开和关闭

1.流

        程序的数据需要输出到外部设备,也需要从外部设备输入。对于不同设备,输入输出方式各有不同。为了方便我们在对各种输入输出设备进行操作,就有了“流”这一高度抽象的概念。在c语言中,对文件,画面,键盘等的输入输出操作都是同过“流”进行的。在一般情况下,我们想要写入数据或者读取数据,都需要打开流。

2.标准流

        c语言程序在启动的时候,默认有三个流已经为我们打开:

stdin--标准输入流,绝大多数情况下从键盘输入。

stdout--标准输出流,绝大多数情况输出至显示器上。

stderr--标准错误流,绝大多数情况输出至显示器上。

正因为这三个流已经默认打开,所以我们使用scanf、printf等函数就可以直接进行输入输出操作。

这三个流也是具有类型的,它们的类型是:文件指针(FILE*)。我们在进行文件操作的时候,通过文件指针变量就可以间接找到与它关联的文件

3.文本文件和二进制文件

        根据数据的组织形式,数据文件被称为文本文件或者二进制文件。 数据在内存中以二进制的形式存储,如果不加转换的输出到外存的文件中,就是二进制文件

        如果要求在外存上以ASCII码的形式存储,则需要在存储前转换。以ASCII字符的形式存储的文件就是文本文件

        ⼀个数据在文件中是怎么存储的呢?

        字符⼀律以ASCII形式存储,数值型数据既可以以ASCII形式存储,也可以使用二进制形式存储。如有整数10000,如果以ASCII码的形式输出到磁盘,则磁盘中占用5个字节(每个字符⼀个字节),而二进制形式输出,则在磁盘上只占4个字节。

4.控制文件打开与关闭的函数

        在了解了这些前置知识之后,我们切入正题--打开文件和关闭文件。c语言提供了两个函数,它们分别负责文件的打开和关闭,原型如下:

打开文件:

FILE *

fopen

( const char * filename, const char * mode );

关闭文件:

int

fclose

( FILE * stream );

fopen函数有两个参数,第一个参数是以字符串形式表示的文件名,第二个参数是文件的打开方式,用字符串表示。这个函数在使用的时候我们需要创建一个文件指针变量来接收,当文件打开失败时,它会返回空指针。关于打开方式,在这里一一列举:

打开方式 含义 如果指定的文件不存在
“r”(只读)

为了输⼊数据,打开⼀个已经存在的⽂本⽂件

返回空指针
“w”(只写)

为了输出数据,打开⼀个⽂本⽂件

建⽴⼀个新的⽂件
“a”(追加) 向⽂本⽂件尾添加数据 建⽴⼀个新的⽂件
“rb”(只读) 为了输⼊数据,打开⼀个⼆进制⽂件 返回空指针
“wb”(只写) 为了输出数据,打开⼀个⼆进制⽂件 建⽴⼀个新的⽂件
“ab”(追加) 向⼀个⼆进制⽂件尾添加数据 建⽴⼀个新的⽂件
“r+”(读写) 为了读和写,打开⼀个⽂本⽂件 返回空指针
“w+”(读写) 为了读和写,建立一个新的文本文件 建⽴⼀个新的⽂件
“a+”(读写) 打开⼀个⽂件,在⽂件尾进⾏读写 建⽴⼀个新的⽂件
“rb+”(读写) 为了读和写打开⼀个⼆进制⽂件 返回空指针

“wb+”(读写)

为了读和写,建立⼀个新的⼆进制⽂件 建⽴⼀个新的⽂件

“ab+”(读写)

打开⼀个⼆进制⽂件,在⽂件尾进⾏读和写 建⽴⼀个新的⽂件

对于fclose函数,它的参数是文件指针,用于关闭这个文件指针指向的文件。

接下来,我们尝试打开和关闭一个文件:

<code>#include <stdio.h>

int main()

{

FILE* pf = fopen("test.txt", "w");

if (pf == NULL)//文件打开失败则退出程序

{

perror("fopen");

return 0;

}

printf("文件打开成功\n");

fclose(pf);

pf = NULL;//避免出现野指针,及时制空

return 0;

}

运行结果:

可以看到,由于打开方式是“w”,该路径下确实出现了一个名为“test.txt”的文件

二、文件的顺序读写

        接下来介绍几个函数,用于在文件当中读取或者写入数据

函数名 功能 适⽤于
fgetc 字符输⼊函数 所有输⼊流
fputc 字符输出函数 所有输出流
fgets ⽂本⾏输⼊函数 所有输⼊流
fputs ⽂本⾏输出函数 所有输出流
fscanf 格式化输⼊函数 所有输⼊流
fprintf 格式化输出函数 所有输出流
fread ⼆进制输⼊ ⽂件输⼊流
fwrite ⼆进制输出 ⽂件输出流

接下来我们尝试使用一下fscanffprintf函数:

这两个函数的第一个参数是一个文件指针,用于对文件数据进行读取和写入操作。之后的参数与scanf、printf函数相同。

<code>#include <stdio.h>

int main()

{

FILE* pf = fopen("test.txt", "w");//要写入数据,以写的形式打开文件

if (pf == NULL)

{

perror("fopen");

return 0;

}

fprintf(pf, "123456");//向文件中写入数据

fclose(pf);

pf = NULL;

return 0;

}

可以看到,数据已经写入到文件当中了。接下来我们使用fscanf函数将文件数据打印到屏幕上:

<code>#include <stdio.h>

int main()

{

char str[20] = { 0 };

FILE* pf = fopen("test.txt", "r");//要读取数据,以读的形式打开文件

if (pf == NULL)

{

perror("fopen");

return 0;

}

fscanf(pf, "%s", str);//读取数据到str当中

printf(str);

fclose(pf);

pf = NULL;

return 0;

}

运行结果:

三、文件的随机读写

1.fseek函数

        fseek函数的作用是根据文件指针的位置和偏移量来定位文件指针。它的原型如下:

int fseek ( FILE * stream, long int offset, int origin );

它的第一个参数是文件指针,第二个参数是相对于设置位置的偏移量,第三个参数是设置的位置。

c语言定义了三个,可选择其中一个作为第三个参数:

SEEK_SET:文件的起始位置

SEEK_CUR:文件指针当前的位置

SEEK_END:文件的末尾

定位了文件指针之后,我们就可以在文件的指定位置处进行读取或者写入操作了。

2.ftell函数

        ftell函数用于返回文件指针相对于起始位置的偏移量。函数原型:

long int ftell ( FILE * stream );

3.rewind函数

        rewind函数用于将文件指针的位置回到文件的起始位置。它的函数原型:

void rewind ( FILE * stream );

四、文件读取结束的判定

        1.对于文本文件,我们首先可以使用fgetc函数循环读取文件中的字符,直到读到EOF为止,说明文件读取结束

        2.对于二进制文件,我们使用fread函数判断其返回值:是否小于实际要读的个数。如果小于,则说明读取结束。

        对于以上两种情况,文件读取结束时,我们可以继续判断文件读取结束的原因。介绍两个函数:feofferror

        feof函数用于判断文件读取结束的原因是否是遇到文件尾。它的原型如下:

int feof ( FILE * stream );

如果文件由于读取到文件末尾而读取结束,则返回EOF;如果是其他情况,则会返回0。

        ferror函数用于判断文件读取结束的原因是否是出现I/O错误。原型如下:

int ferror ( FILE * stream );

如果文件由于出现I/O错误而读取结束,则返回非0值;其他情况则返回0。

接下来我们尝试写一段代码对文件读取结束进行判断:

<code>#include <stdio.h>

int main()

{

int c = 0;

FILE* fp = fopen("test.txt", "r");

if (fp == NULL)

{

perror("fopen");

return 0;

}

while ((c = fgetc(fp)) != EOF)//返回EOF则读取结束

{

putchar(c);

}

//判断读取结束的原因

if (ferror(fp))

puts("I/O错误\n");

else if (feof(fp))

puts("文件读取结束\n");

fclose(fp);

fp = NULL;

return 0;

}

总结

        今天我们学习了文件操作相关的知识,了解了文件的打开关闭,写入数据或者从文件读取数据的方法,以及调整文件指针的函数,还有对文件读取结束的判定。如果你觉得博主讲的还不错,就请留下一个小小的赞在走哦,感谢大家的支持❤❤❤



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。