C语言各种关于的文件操作(最详细)

一.为什么使用文件

有时候我们在写程序时,当程序运行起来的时候可以给数据进行操作,此时的数据是存放在内存中,当程序运行结束时,程序里面的数据自然就不存在了。等下次运行程序时我们又要重新输入。

这样就给我们带来了许多不便。因此,我们需要把数据持久保存起来。我们一般数据持久化的方法有,把数据存放在磁盘文件,存放到数据库等方式。使用文件我们可以将数据直接存放在电脑的硬盘上,做到了数据的持久化。

二.什么是文件

磁盘上的文件就是文件。

但是在程序设计中,我们一般谈的文件有两种:程序文件、数据文件(从文件功能的角度分类的)。

1.程序文件

包括源程序文件(后缀为.c)、目标文件(windows环境下后缀为.obj)、可执行文件(windows环境下后缀为.exe)。

2.数据文件

文件的内容不一定是程序,而是程序运行时读写的数据,比如程序运行需要从中读取数据的文件,或者输出内容的文件。有时候我们会把信息输出到磁盘上,当需要的时候再从磁盘上把数据读取到内存中使用,这里处理的就是磁盘上的文件。

3.文件名

一个文件要有一个唯一的文件标识,以便用户识别和引用。

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

例如:

三.文件的打开和关闭

1.缓冲文件系统中,关键的概念是“文件类型指针”,简称“文件指针”。

每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名字、文件状态及文件当前位置等)。这些信息是保存在一个结构体变量中。该结构体类型是由系统声明的,取名 FILE.

例如,vs code编译环境提供的 stdio.h头文件中有以下的文件类型声明:

不同的c 编译器的 FILE 类型包含的内容不完全相同,但是大同小异。

每次打开一个文件的时候,系统会根据文件的情况自动创建一个 FILE 结构的变量,并填充其中的信息。

一般都是通过 FILE 的指针来维护这个 FILE 结构的变量,这样使用起来更加方便。

 

定义 pf 是一个指向 FILE 类型数据的指针变量。可以使 pf 指向某个文件的文件信息区(是一个结构体变量)。通过该文件信息区中的信息就能够访问该文件。也就是说:通过文件指针变量能够找到与他关联的文件。

2.文件的打开与关闭

文件在进行读写操作之前应该先打开文件,在使用结束后应该关闭文件。

在编写程序时,在打开文件的同时,都会返回一个 FILE*的指针变量指向该文件,也相当于建立了指针和文件的关系。

ANSIC 规定使用 fopen 函数来打开文件,fclose 函数来关闭文件,使用前记得包含头文件stdlib.h

例如:

打开方式如下: 

四.文件的顺序读写

1.字符串输入\输出函数:fgetc\fputc,适用于所有输入\输出流。

返回值为 int 类型,函数参数为文件指针类型。该函数如果读取失败或者读到文件结尾则会返回 EOF 的值并且在该位置位置标记失败信息,读取成功时会返回读取到的字符。

fputc 是 file output char 的所以,意思是向指定的文件中写入一个字符。int character 为要写入的内容,FILE* stream为要写入的文件的指针。

我们来举个例子就知道了,我们要把 data 里面的内容复制到 data_cpy里代码如下:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    FILE* pfread=fopen("data.txt","r");//以读的方式打开
    if(pfread==NULL)//判断是否打开成功
    {
        perror("fopen");
        return 1;
    }
    FILE* pfwrite=fopen("data_cpy,txt","w");//以写的方式打开
    if(pfwrite==NULL)
    {
        perror("fopen");
        fclose(pfread);
        return 1;
    }
    //开读写文件
    int ch=0;
    while((ch=fgetc(pfread))!=EOF)//一个一个的读
    {
        fputc(ch,pfwrite);//一个一个的写
    }
    int ret=feof(pfread);//判断文件为什么结束
    printf("%d\n",ret);
    int ret1=ferror(pfread);//用来判断文件是否出错
    printf("%d\n",ret1);
    //关闭文件
    fclose(pfread);
    pfread=NULL;
    fclose(pfwrite);
    pfwrite=NULL;
    return 0;
}

2.文本行输入输出函数:fgets/fputs,适用于所有输出流。

str 指的是要保存到的内存空间的首地址,num 指的是读取的字符串的长度,stream表示从何种流中读取,可以是标准输入流 stdin,也可以是文件流,即从某个文件中读取。

举个例子:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    char arr[10]={0};//创建一个大小为十个元素的字符数组
    FILE* pf=fopen("data.txt","r");
    if(pf==NULL)
    {
        perror("fopen");
        return 1;
    }
    //读文件并写到 arr 中
    fgets(arr,10,pf);
    printf("%s\n",arr);
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

注意:fgets() 函数中的 size 如果小于字符串的长度,那么字符串将会被截取;如果 size 大于字符串的长度则多余的部分系统会自动用 '\0' 填充。所以假如你定义的字符数组长度为 n,那么 fgets() 中的 size 就指定为 n–1,留一个给 '\0' 就行了。

fputs函数:

作用:写一串字符串到流当中,适用于所有输出流

书写成功返回非0值,若书写失败返回EOF。

#include <stdio.h>
#include <stdlib.h>
int main()
{
    FILE* pf=fopen("data.txt","w");//以写的方式打开
    if(pf==NULL)
    {
        perror("fopen");
        return 1;
    }
    //开始写文件
    fputs("abcdaadadadadada",pf);//将字符串写入文件中
    //关闭文件
    fclose(pf);
    pf=NULL;
    return 0;
}

3.fscanf/fprintf,格式化输入输出函数,适用于所有输入输出流。

举个例子:

4.二进制输入输出

 fread函数:二进制输入流,适用于文件输入

以下是运行实例:

#include <stdio.h>
#include <stdlib.h>


struct S
{
    char name[20];
    int age;
    float score;
};

int main()
{
    struct S s={"lisi",21,98.7f};
    //以二进制读
    FILE* pf=fopen("data.txt","rb");
    if(pf==NULL)
    {
        perror("fopen");
        return 1;
    }
    //开始读
    fread(&s,sizeof(struct S),1,pf);
    printf("%s %d %f\n",s.name,s.age,s.score);

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

fwrite函数:二进制输出流,适用于文件输出

例子:

#include <stdio.h>
#include <stdlib.h>


struct S
{
    char name[20];
    int age;
    float score;
};

int main()
{
    struct S s={"lisi",21,98.7f};
    //以二进制写入文件中
    FILE* pf=fopen("data.txt","wb");
    if(pf==NULL)
    {
        perror("fopen");
        return 1;
    }
    //开始写
    fwrite(&s,sizeof(struct S),1,pf);

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

五.文件的随机读写

1.fseek

根据文件指针的 位置和偏移量;来定位文件指针.

#include <stdio.h>
#include <stdlib.h>
int main()
{
    FILE* pf=fopen("data.txt","w");
    fputs("abcdef",pf);
    fseek(pf,3,SEEK_SET);
    fputs(" sam",pf);
    fclose(pf);
    pf=NULL;
    return 0;
}

2.ftell

返回文件指针相对于起始位置的偏移量。


long int ftell ( FILE * stream );

例子:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    long size;
    FILE* pf=fopen("data.txt","w");
    fputs("abcdef",pf);
    fseek(pf,3,SEEK_SET);
    fputs(" sam",pf);
    size=ftell(pf);
    printf("%ld\n",size);
    fclose(pf);
    pf=NULL;
    return 0;
}

3.rewind

让文件指针回到文件的起始位置。

 void rewind ( FILE * stream );

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值