1. 文件操作概述

在 C 语言中,提供了一个 FILE 类型,用于处理操作文件内容,主要涉及到文件的读(Read)写(Write)操作,另外文件操作涉及到文件资源,需要注意冲突问题。

2. 文件打开函数 fopen

FILE * fopen(const char * file_path, const char * mode);

函数功能: 根据用户提供的文件路径file_path,以及对应文件的打开方式 mode 打开目标文件,打开成功返回对应文件指针,如果目标文件不存在或者不具备相关模式权限, 返回 NULL

参数解释:

  • file_path: 用户指定的文件路径字符串,可以是相对路径,也可以是绝对路径。
  • mode: 打开当前文件方式字符串,有特定的约束和要求

返回值解释:

  • 返回值是 FILE 类型指针,文件打开成功返回当前文件内容在内存空间首地址,打开失败返回 NULL

文件打开方式表格

模式 描述
r 打开一个已有的文本文件,允许读取文件。
w 打开一个文本文件,允许写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会从文件的开头写入内容。如果文件存在,文件内容会被清空**【删除写/清空写】。**
a 打开一个文本文件,以追加模式写入文件。如果文件不存在,则会创建一个新文件。在这里,您的程序会在已有的文件内容中追加内容。【追加写】
r+ 打开一个文本文件,允许读写文件。
w+ 打开一个文本文件,允许读写文件。如果文件已存在,则文件会被截断为零长度,如果文件不存在,则会创建一个新文件【截断写】。
a+ 打开一个文本文件,允许读写文件。如果文件不存在,则会创建一个新文件。读取会从文件的开头开始,写入则只能是追加模式。

如果文件是二进制形式,需要添加模式参数 b

"rb", "wb", "ab", "rb+", "r+b", "wb+", "w+b", "ab+", "a+b"

3. 文件关闭函数 fclose

int fclose(FILE *fp);

函数功能: 将用户提供的 FILE 文件指针对应文件进行关闭操作,同时会将修改的文件内容保存到硬盘中。

参数解释:

  • fp: 用户提供 FILE 文件指针

返回值解释:

  • 如果成功关闭文件,fclose( ) 函数返回零,如果关闭文件时发生错误,函数返回 EOF
  • EOF(End Of File) 是 -1

4. 文件内容写入操作

int fputc(int c, FILE *fp);

函数功能: 将用户提供的字符数据,写入到对应的 FILE 文件指针对应文件要求,要求 FILE 指针对应的文件必须具备写入能力,要求打开的模式为 [w or a]

参数解释:

  • c: 参数类型是一个 int 类型,但是实际写入到文件中的数据内容是 int 类型的【低 8 位】
  • fp: 用户提供 FILE 文件指针

返回值解释:

  • 写入成功返回值大于 - 1,如果写入失败返回 EOF(-1)
int fputs(const char *s, FILE *fp);

函数功能: 将用户提供的字符串数据,写入到对应的 FILE 文件指针对应文件要求,要求 FILE 指针对应的文件必须具备写入能力,要求打开的模式为 [w or a]

参数解释:

  • s: 用户提供的字符串数据
  • fp: 用户提供 FILE 文件指针

返回值解释:

  • 写入成功返回值大于 - 1,如果写入失败返回 EOF(-1)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
int fputs(const char *s, FILE *fp);
int fputc(int c, FILE *fp);
*/
int main(int argc, char const *argv[])
{
    FILE *fp = fopen("./data/1.txt", "a");

#if 0
    fputc('A', fp);
    fputc('B', fp);
    fputc('C', fp);
    fputc('D', fp);
    fputc('E', fp);
    fputc('F', fp);
    fputc('\n', fp);
#endif
    fputs("[ID:2,Name:Wade,Age:42,Gender:M,Math:90,Chinese:90,English:75]\n", fp);

    fclose(fp);
    return 0;
}

5. 文件内容读取操作

int fgetc(FILE * fp);

函数功能: 根据用户提供的 FILE 文件指针,从文件中读取一个字节数据,返回值为 int 类型,但是实际有效数据是 int 类型的低 8 位

参数解释:

  • fp: 用户提供 FILE 文件指针,要求必须是 [r r+ w+ a+]

返回值解释:

  • 返回值是读取到的字节数据,如果读取到文件末尾返回 EOF(-1)
char *fgets(char *buf, int n, FILE *fp);

函数功能: 根据用户提供的 FILE 文件指针,从文件中 0 ~ n - 1 个字节,读取字节数据存储到 buf 字符数组中,要求提供的缓冲区必须有足够的内存空间。返回值是 buf 空间首地址。读取过程中如果读取到 '\n' 或者 EOF 停止读取

参数解释:

  • buf:char 类型缓冲区,可以是一个静态数组,也可以是动态分配的连续内存空间,通常情况下会采用 64 128 256 512 字节个数
  • n:本次读取的期望字节个数,根据文件中的情况读取到的字符个数为 0 ~ n - 1。
  • fp: 用户提供 FILE 文件指针,要求必须是 [r r+ w+ a+]

返回值解释:

  • 返回值是 buf 空间首地址
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

/*
int fgetc(FILE * fp);
char *fgets(char *buf, int n, FILE *fp);
*/
int main(int argc, char const *argv[])
{
    FILE *fp = fopen("./data/1.txt", "r");
#if 0
    int content = EOF;

    while ((content = fgetc(fp)) != EOF)
    {
        printf("%c", content);
    }
#endif
    char *buf = (char *)calloc(128, 1);

    while (fgets(buf, 128, fp))
    {
        printf("%s", buf);
        memset(buf, 0, 128);
    }

    free(buf);
    fclose(fp);
    return 0;
}