C语言提供了一组文件操作函数,用于对文件进行读取、写入、打开、关闭等操作。下面将介绍常用的文件操作函数。

本文包含了文件操作的大部分知识内容,如果只是应付考试,请点击这里查看考试范围内的内容

一、打开和关闭文件

文件操作的第一步是打开文件。C语言中使用 fopen() 函数打开文件,其原型如下:

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

filename 参数是要打开的文件的文件名,mode 参数是文件打开模式,通常有以下几种模式:

  • “r”:只读模式,打开一个已有的文本文件,文件指针在文件的开头。
  • “w”:只写模式,打开一个文本文件,如果文件已存在则文件会被截断为空,文件指针在文件的开头。
  • “a”:追加模式,打开一个文本文件,如果文件已存在则文件指针移到文件的末尾,否则创建一个新文件。
  • “rb”、“wb”、“ab”:二进制模式,与上述模式类似,但是是针对二进制文件的。

如果文件打开成功,函数返回一个指向 FILE 结构体的指针,该结构体包含了与文件有关的信息,如文件指针、缓冲区等。如果文件打开失败,函数返回 NULL

文件操作完成后需要关闭文件,C语言中使用 fclose() 函数关闭文件,其原型如下:

int fclose(FILE *stream);

该函数将 stream 所指向的文件关闭,并将该文件所占用的资源释放掉。如果函数执行成功,返回值为 0,否则返回 EOF

二、读取和写入文件

打开文件之后,可以使用 fscanf()fgets()fread() 等函数读取文件,或使用 fprintf()fputs()fwrite() 等函数向文件中写入数据。

其中,fscanf() 函数用于从文件中读取格式化的数据,其原型如下:

int fscanf(FILE *stream, const char *format, ...);

stream 参数是指向要读取的文件的指针,format 参数是格式控制字符串,后面的参数根据格式控制字符串指定的格式来读取文件中的数据。

fgets() 函数用于从文件中读取一行字符串,其原型如下:

char *fgets(char *s, int size, FILE *stream);

fgets()stream 指向的文件中读取一行,最多读取 size - 1 个字符,将它们存储到 s 指向的字符数组中,最后加上一个空字符 ‘\0’。如果读取到文件末尾或出现错误,返回 NULL

fread() 函数用于从文件中读取二进制数据,其原型如下:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

ptr参数是要读取数据的缓冲区指针,size 参数是要读取的每个数据项的字节数,nmemb 参数是要读取的数据项的数量,stream 参数是指向要读取的文件的指针。fread() 函数返回成功读取的数据项数目。

fprintf() 函数用于向文件中写入格式化的数据,其原型如下:

int fprintf(FILE *stream, const char *format, ...);

stream 参数是指向要写入的文件的指针,format 参数是格式控制字符串,后面的参数根据格式控制字符串指定的格式来写入数据。

fputs() 函数用于向文件中写入字符串,其原型如下:

int fputs(const char *s, FILE *stream);

fputs() 将字符串 s 写入到 stream 指向的文件中,如果成功,返回一个非负整数,否则返回 EOF

fwrite() 函数用于向文件中写入二进制数据,其原型如下:

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);

ptr 参数是要写入的数据的缓冲区指针,size 参数是要写入的每个数据项的字节数,nmemb 参数是要写入的数据项的数量,stream 参数是指向要写入的文件的指针。fwrite() 函数返回成功写入的数据项数目。

三、示例

下面是一个示例程序,演示了如何使用文件操作函数读取和写入文件:

#include <stdio.h>

int main()
{
    FILE *in_file, *out_file;
    char in_filename[] = "input.txt";
    char out_filename[] = "output.txt";
    char buffer[256];

    in_file = fopen(in_filename, "r");
    if (in_file == NULL) {
        printf("Failed to open input file!\n");
        return 1;
    }

    out_file = fopen(out_filename, "w");
    if (out_file == NULL) {
        printf("Failed to open output file!\n");
        return 1;
    }

    while (fgets(buffer, sizeof(buffer), in_file)) {
        fprintf(out_file, "%s", buffer);
    }

    fclose(in_file);
    fclose(out_file);

    return 0;
}

该程序将打开一个名为 “input.txt” 的文件,逐行读取文件中的数据,然后将数据写入一个名为 “output.txt” 的文件中。如果文件打开失败,程序将输出错误消息,并返回一个非零值。否则,程序将返回零。

1. 文件定位

文件操作中常用的一个概念是文件定位。文件定位指的是在文件中的某个位置读取或写入数据。

在 C 语言中,使用 fseek() 函数进行文件定位。其原型如下:

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

stream 参数是要定位的文件指针,offset 参数是定位的偏移量,whence 参数是定位的起始位置。

whence 参数可以取以下值:

  • SEEK_SET:从文件开头计算偏移量。
  • SEEK_CUR:从当前位置计算偏移量。
  • SEEK_END:从文件结尾计算偏移量。

例如,要将文件指针移动到文件开头,可以使用如下代码:

fseek(fp, 0, SEEK_SET);

2. 文件截取

有时候,需要截取文件的一部分,或者将文件扩展到一个更大的尺寸。在 C 语言中,可以使用 ftruncate() 函数截取文件。其原型如下:

int ftruncate(int fd, off_t length);

fd 参数是文件描述符,length 参数是截取后文件的大小。如果截取成功,ftruncate() 函数将返回零,否则返回 -1。

3. 错误处理

在文件操作中,如果出现错误,需要进行错误处理。C 语言提供了 perror()ferror() 函数来处理文件操作的错误。

perror() 函数可以打印出一个错误消息,并输出一个与当前错误号对应的错误消息。其原型如下:

void perror(const char *s);

s 参数是一个字符串,用于描述发生错误的上下文信息。例如,下面的代码可以输出 “Failed to open file: input.txt”:

FILE *fp = fopen("input.txt", "r");
if (fp == NULL) {
    perror("Failed to open file");
}

ferror() 函数可以检查文件操作是否出现了错误。其原型如下:

int ferror(FILE *stream);

stream 参数是要检查的文件指针。如果文件操作出现了错误,ferror() 函数将返回一个非零值,否则返回零。

4. 文件操作示例

下面是一个使用文件操作的示例程序。该程序从一个文本文件中读取数据,将其转换为大写形式,并输出到另一个文件中。

#include <stdio.h>
#include <ctype.h>

int main() {
    FILE *fp_in = fopen("input.txt", "r");
    if (fp_in == NULL) {
        perror("Failed to open input file");
        return 1;
    }

    FILE *fp_out = fopen("output.txt", "w");
    if (fp_out == NULL) {
        perror("Failed to open output file");
        return 1;
    }

    int c;
    while ((c = fgetc(fp_in)) != EOF) {
        fputc(toupper(c), fp_out);
    }

    if (ferror(fp_in)) {
        perror("Error reading input file");
        return 1;
    }

    if (ferror(fp_out)) {
        perror("Error writing output file");
        return 1;
    }

    fclose(fp_in);
    fclose(fp_out);

    return 0;
}

该程序首先使用 fopen() 函数打开输入文件和输出文件,如果文件打开失败,就输出一个错误消息并退出。

接下来,程序使用 fgetc() 函数从输入文件中读取一个字符,并使用 toupper() 函数将其转换为大写形式。然后,程序使用 fputc() 函数将字符写入输出文件中。

程序通过检查 ferror() 函数来检查文件操作是否出现错误。如果出现错误,就输出一个错误消息并退出。

最后,程序使用 fclose() 函数关闭输入文件和输出文件。

四、大一基础综合案例

大一C语言基础部分需要掌握的文件操作部分包括:

  1. 文件打开和关闭:使用 fopen() 函数打开文件,并使用 fclose() 函数关闭文件。
  2. 文件读取和写入:使用 fread()fwrite() 函数进行二进制数据的读写;使用 fscanf()fprintf() 函数进行文本数据的读写。
  3. 文件定位:使用 fseek() 函数进行文件定位,可以在文件中的任何位置读取或写入数据。
  4. 文件错误处理:使用 ferror()perror() 函数处理文件操作中的错误。

注意:文件定位错误处理 不是重点掌握内容,考生仅需掌握文件的打开读写关闭这三部曲。

下面是一个综合性的文件操作示例,该程序从输入文件中读取整数,计算它们的平均值,并将结果写入输出文件中。

#include <stdio.h>

int main() {
    FILE *fp_in = fopen("input.txt", "r");
    if (fp_in == NULL) {
        perror("Failed to open input file");
        return 1;
    }

    FILE *fp_out = fopen("output.txt", "w");
    if (fp_out == NULL) {
        perror("Failed to open output file");
        return 1;
    }

    int n = 0;
    int sum = 0;
    int x;
    while (fscanf(fp_in, "%d", &x) == 1) {
        sum += x;
        n++;
    }

    if (ferror(fp_in)) {
        perror("Error reading input file");
        return 1;
    }

    if (n > 0) {
        double avg = (double) sum / n;
        fprintf(fp_out, "Average: %.2f", avg);
    } else {
        fprintf(fp_out, "No data");
    }

    if (ferror(fp_out)) {
        perror("Error writing output file");
        return 1;
    }

    fclose(fp_in);
    fclose(fp_out);

    return 0;
}

该程序首先使用 fopen() 函数打开输入文件和输出文件,如果文件打开失败,就输出一个错误消息并退出。

接下来,程序使用 fscanf() 函数从输入文件中读取整数,并计算它们的平均值。如果输入文件中没有数据,程序将在输出文件中输出 “No data”。

程序通过检查 ferror() 函数来检查文件操作是否出现错误。如果出现错误,就输出一个错误消息并退出。

最后,程序使用 fclose() 函数关闭输入文件和输出文件。