【c语言】玩转文件操作

简介: 本文介绍了C语言中文件操作的基础知识,包括文件的打开和关闭、文件的顺序读写、文件的随机读写以及文件读取结束的判定。详细讲解了`fopen`、`fclose`、`fseek`、`ftell`、`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函数,它的参数是文件指针,用于关闭这个文件指针指向的文件。


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

#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 ⼆进制输出 ⽂件输出流

接下来我们尝试使用一下fscanf和fprintf函数:


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

#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函数将文件数据打印到屏幕上:

#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函数判断其返回值:是否小于实际要读的个数。如果小于,则说明读取结束。


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


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


int feof ( FILE * stream );


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


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


int ferror ( FILE * stream );


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


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

#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;
}

总结

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

相关文章
|
1月前
|
存储 C语言
C语言文件操作(2)
【10月更文挑战第2天】
|
1月前
|
程序员 编译器 C语言
C语言底层知识------文件操作
本文详细介绍了文件操作的基本概念,包括文件的分类(程序文件和数据文件,其中着重于数据文件的文本文件和二进制文件),流的概念及其在C程序中的应用,以及标准输入输出流stdin、stdout和stderr的作用。作者通过示例展示了如何使用fopen、fclose和常见的读写函数如fgetc、fputc和fgets进行文件操作。
21 2
|
2月前
|
C语言
C语言——文件操作
本文介绍了文件的基本操作,包括文件的打开、关闭、读取和写入。使用`fopen`函数以不同模式(如“r”、“w”等)打开文件,并通过`fclose`关闭。文章详细解释了如何利用`fputc`、`fputs`及`fprintf`进行格式化写入,同时介绍了`fgetc`、`fgets`和`fscanf`用于文件内容的读取。此外,还涵盖了二进制文件的读写方法以及如何通过`fseek`、`ftell`和`rewind`实现文件的随机访问。
50 1
C语言——文件操作
|
1月前
|
存储 缓存 编译器
文件操作——C语言
文件操作——C语言
|
1月前
|
存储 C语言
简述C语言文件操作
简述C语言文件操作
11 0
|
1月前
|
存储 文件存储 C语言
深入C语言:文件操作实现局外影响程序
深入C语言:文件操作实现局外影响程序
|
1月前
|
存储 程序员 编译器
C语言文件操作(1)
【10月更文挑战第1天】
|
1月前
|
存储 C语言
C语言的文件操作
C语言的文件操作
21 0
|
1月前
|
存储 移动开发 Unix
C 语言文件操作详解
C 语言文件操作详解
|
2月前
|
存储 C语言
C语言程序设计核心详解 第十章:位运算和c语言文件操作详解_文件操作函数
本文详细介绍了C语言中的位运算和文件操作。位运算包括按位与、或、异或、取反、左移和右移等六种运算符及其复合赋值运算符,每种运算符的功能和应用场景都有具体说明。文件操作部分则涵盖了文件的概念、分类、文件类型指针、文件的打开与关闭、读写操作及当前读写位置的调整等内容,提供了丰富的示例帮助理解。通过对本文的学习,读者可以全面掌握C语言中的位运算和文件处理技术。