C 读取文件

在 C 语言中,如果读取文件中的数据,只需要以下简单的 3 步。

  • 打开文件:使用 fopen() 函数打开文件。
  • 读取数据:使用 fscanf()、fgets()、fread()、fgetc() 等函数从文件中读取数据。
  • 关闭文件:使用 fclose() 函数关闭文件。

C 打开和关闭文件

在 C 语言中,如果想要读取一个文件,首先我们要学会如何打开一个文件和关闭一个文件。

1. C 打开文件

在 C 语言中,如果想要读取一个文件,我们必须先使用 fopen() 函数打开文件。fopen() 函数返回一个指向 FILE 类型的指针,该指针用于后续的文件操作。

语法:

FILE *fopen(filename, mode);

说明:

fopen() 函数接收以下 2 个参数。

  • filename(const char *):要打开的文件名(包括路径)。
  • mode(const char *):打开文件的模式,指定文件的访问方式。常用的读取模式有以下几种:
    • "r":只读模式,文件必须存在。
    • "rb":只读模式,用于二进制文件。
    • "r+":读写模式,文件必须存在。
    • "rb+":读写模式,用于二进制文件。

如果文件打开成功,则 fopen() 函数会返回一个指向 FILE 结构体的指针。如果打开失败(如文件不存在),则 fopen() 函数返回 NULL。因此,在进行文件操作之前,一定要检查返回值是否为 NULL。

接下来在当前项目根目录下创建一个名为 “files” 的目录,然后在 files 目录中创建一个 data.txt 文件,整个项目结构如下图所示。

C 读取文件项目 1

示例 1:使用 fopen() 打开文件

#include <stdio.h>

int main(void) 
{
    FILE *fp;
    const char *filename = "./files/data.txt";      // 使用字符串指针

    // 尝试以只读模式(r)打开文件
    fp = fopen(filename, "r");

    // 检查文件是否成功打开
    if (fp == NULL) 
    {
        printf("无法打开文件:%s\n", filename);
        return 1;       // 表示程序出错
    } 
    else 
    {
        printf("成功打开文件:%s\n", filename);
        fclose(fp);     // 关闭文件
        return 0;       // 表示程序正常结束
    }
}

运行结果如下。

成功打开文件:./files/data.txt

分析:

在上面例子中,我们尝试以只读模式 ("r") 打开名为 "/files/data.txt" 的文件。如果 fopen() 函数返回 NULL,则说明文件打开失败,此时程序会打印错误信息并退出。如果 fopen() 函数不返回 NULL,则说明表示文件成功打开,此时程序会打印成功信息并使用 fclose() 函数关闭文件。

2. C 关闭文件

在完成文件读取操作后,我们一定要使用 fclose() 函数关闭文件,这样做的目的是释放系统资源并确保数据被正确写入(对于写入操作)。

语法:

int fclose(stream);

说明:

fopen() 函数接收单个参数。

  • stream(FILE *):指向要关闭的文件的 FILE 指针。

如果文件成功关闭,则 fclose() 函数返回 0。如果发生错误,则 fclose() 函数返回 EOF。

C 使用 fscanf() 函数读取文件

在 C 语言中,fscanf() 函数类似于 scanf(),不过 fscanf() 函数是从文件中读取格式化的数据。

语法:

int fscanf(stream, format, ...);

说明:

fscanf() 函数接收以下 3 种参数。

  • stream(FILE *):指向已打开文件的 FILE 指针。
  • format(const char *):格式化字符串,指定要读取的数据类型和格式。
  • ...:可变参数列表,用于存储读取到的数据。

fscanf() 函数会返回成功读取的参数个数。如果在读取过程中遇到文件结束符(EOF)或错误,则返回 EOF。

接下来,我们在 files 目录的 data.txt 文件中写入以下内容:

666 3.14 lvyenet

示例 2:使用 fscanf() 读取文件内容

#include <stdio.h>

int main(void) 
{
    FILE *fp;
    int num;
    float pi;
    char str[20];

    fp = fopen("./files/data.txt", "r");
    if (fp == NULL) 
    {
        printf("无法打开文件\n");
        return 1;
    }

    // 从文件中读取整数、浮点数和字符串
    int result = fscanf(fp, "%d %f %s", &num, &pi, str);

    if (result == 3) 
    {
        printf("读取成功:num = %d, pi = %f, str = %s\n", num, pi, str);
    } 
    else 
    {
        printf("读取文件失败或到达文件末尾。\n");
    }
    fclose(fp);

    return 0;
}

运行结果如下。

读取成功:num = 666, pi = 3.140000, str = lvyenet

分析:

在这个例子中,我们使用 fscanf() 函数从 "data.txt" 文件中读取一个整数、一个浮点数和一个字符串,并将它们分别存储在 num、pi、str 这 3 个变量中。其中,格式化字符串 " %d %f %s" 指定了要读取的数据类型。

C 使用 fgets() 函数读取一行

在 C 语言中,我们可以使用 fgets() 函数来从文件中读取一行字符串,直到遇到换行符 (\n)、文件结束符(EOF)或者读取了 n-1 个字符为止。

语法:

char *fgets(str, n, FILE);

说明:

fgets() 函数接收以下 3 种参数。

  • str(char *):指向用于存储读取到的字符串的字符数组的指针。
  • n(int):要读取的最大字符数(包括空字符 \0)。
  • stream(*stream):指向已打开文件的 FILE 指针。

如果读取成功,fgets() 函数会返回指向 str 的指针。如果遇到文件结束符且未读取任何字符,或者发生错误,则返回 NULL。

接下来,我们在 files 目录中创建一个 lines.txt 文件,整个项目结构如下图所示。

C 读取文件项目 2

然后往 lines.txt 文件写入以下内容:

This is C
This is C++
This is C#

示例 3:使用 fgets() 读取文件中的每一行

#include <stdio.h>

int main(void) 
{
    FILE *fp;
    char line[100];       // 假设每行不超过 99 个字符

    fp = fopen("./files/lines.txt", "r");
    if (fp == NULL) 
    {
        printf("无法打开文件\n");
        return 1;
    }

    // 逐行读取文件内容
    while (fgets(line, sizeof(line), fp) != NULL) 
    {
        printf("%s", line);
    }
    fclose(fp);

    return 0;
}

运行结果如下。

This is C
This is C++
This is C#

分析:

在上面例子中,我们使用 while 循环 和 fgets() 函数逐行读取 "lines.txt" 文件的内容,并将每一行打印到控制台上。循环会一直执行,直到 fgets() 返回 NULL(表示到达文件末尾或发生错误)。

此外,fgets() 会将换行符也读入字符串中,处理时可能需要手动去除。

C 使用 fgetc() 函数读取单个字符

在 C 语言中,我们可以使用 fgetc() 函数来从文件中读取一个字符。

语法:

int fgetc(stream);

说明:

fgetc() 函数接收单个参数。

  • stream(FILE *):指向已打开文件的 FILE 指针。

fgetc() 函数会返回读取到的字符的 ASCII 值(作为一个 int 类型)。如果到达文件末尾或发生错误,则返回 EOF。

接下来,我们在 files 目录中创建一个 site.txt 文件,整个项目结构如下图所示。

C 读取文件项目 3

然后往 site.txt 文件写入以下内容:

lvyenet

示例 4:使用 fgetc() 逐个字符读取文件

#include <stdio.h>

int main(void) 
{
    FILE *fp;
    int ch;

    fp = fopen("./files/site.txt", "r");
    if (fp == NULL) 
    {
        printf("无法打开文件");
        return 1;
    }

    // 逐个字符读取文件内容
    while ((ch = fgetc(fp)) != EOF) 
    {
        printf("%c\n", ch);
    }
    fclose(fp);

    return 0;
}

运行结果如下。

l
v
y
e
n
e
t

分析:

在上面例子中,我们使用 while 循环和 fgetc() 函数逐个字符读取 "site.txt" 文件的内容,并将每个字符打印到控制台上。循环会一直执行,直到 fgetc() 函数返回 EOF。

需要注意的是,这里我们使用 int 类型来接收 fgetc 的返回值,而不是 char。这是因为 EOF 的值通常是 -1,超出标准 char 的范围,因此必须使用 int 才能正确判断。

提示: 除了之前介绍的函数之外,我们还可以使用 fread() 函数来读取二进制数据。不过大多数情况下,我们都不会去读取二进制数据。因此对于 fread() 函数,小伙伴们只需简单了解即可。

上一篇: C 文件路径

下一篇: C 写入文件

给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号