00000002_C语言 文件操作

C语言:文件操作

C语言的文件操作是通过标准库提供的函数来实现的,这些函数可以处理文件的读写、定位等操作。文件操作对于开发数据持久化、处理输入输出(I/O)等功能是非常重要的。

3.1 文件打开、关闭与读写

在C语言中,文件操作主要依赖于标准库 <stdio.h> 中的函数,尤其是 fopenfclosefreadfwrite 等。

  • fopen:用于打开文件。它会返回一个文件指针,之后我们通过该指针对文件进行读写操作。

    语法

    FILE *fopen(const char *filename, const char *mode);
    
    • filename:要打开的文件名(包括路径)。
    • mode:文件的打开模式。常见模式有:
      • "r":只读模式,文件必须存在。
      • "w":写模式,若文件不存在则创建,若存在则清空文件内容。
      • "a":追加模式,文件若不存在则创建,若存在则从文件末尾开始写入。
      • "rb":以二进制模式只读打开文件。
      • "wb":以二进制模式写入文件。
      • "r+":以读写模式打开文件。

    示例代码

    FILE *file = fopen("example.txt", "w");
    if (file == NULL) {
        printf("无法打开文件。\n");
    } else {
        fprintf(file, "Hello, C Programming!\n");
        fclose(file);
    }
    
  • fclose:用于关闭文件,释放文件指针资源。

    语法

    int fclose(FILE *stream);
    

    示例代码

    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        // 文件操作
        fclose(file);
    }
    
  • FILE*:文件指针

    • 定义: FILE * 是 C 标准库中定义的一个结构体指针,专门用于文件操作。该结构体由操作系统管理,程序员通过该指针来操作文件。不同的系统可能略有差异,但是类型名FILE是一样的。
    typedef struct {
        int handle;         // 文件描述符(操作系统级别的文件句柄)
        unsigned char *buf; // 文件的缓冲区
        size_t buf_size;    // 缓冲区的大小
        size_t buf_pos;     // 当前缓冲区的位置
        int flags;          // 文件标志,如读、写等
        long offset;        // 文件的当前偏移量
    } FILE;
    
    • 作用: FILE * 允许程序对文件进行操作,如打开、关闭、读取、写入、定位指针等。

  • fread:从文件中读取数据。

    语法

    size_t fread(void *ptr, size_t size, size_t count, FILE *stream);
    
    • ptr:指向存储读取数据的缓冲区。
    • size:每个数据项的大小(字节数)。
    • count:要读取的数据项个数。
    • stream:文件指针。

    示例代码

    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        char buffer[100];
        size_t bytesRead = fread(buffer, sizeof(char), 100, file);
        buffer[bytesRead] = '\0';  // 确保字符串结束符
        printf("读取的数据: %s\n", buffer);
        fclose(file);
    }
    
  • fwrite:向文件中写入数据。

    语法

    size_t fwrite(const void *ptr, size_t size, size_t count, FILE *stream);
    
    • ptr:指向要写入数据的内存位置。
    • size:每个数据项的大小(字节数)。
    • count:要写入的数据项个数。
    • stream:文件指针。

    示例代码

    FILE *file = fopen("example.bin", "wb");
    if (file != NULL) {
        int numbers[] = {1, 2, 3, 4};
        fwrite(numbers, sizeof(int), 4, file);
        fclose(file);
    }
    
  • fprintf:格式化输出到文件。

    • 语法
    int fprintf(FILE *stream, const char *format, ...);
    
    • 示例:将数据写入文本文件
    FILE *file = fopen("example.txt", "w");
    if (file != NULL) {
        int a = 5;
        float b = 3.14;
        fprintf(file, "整数: %d, 浮点数: %.2f\n", a, b);
        fclose(file);
    }
    
  • fscanf:从文件中格式化输入。

    • 语法
    int fscanf(FILE *stream, const char *format, ...);
    
    • 示例:从文件中读取数据
    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        int a;
        float b;
        fscanf(file, "整数: %d, 浮点数: %f", &a, &b);
        printf("读取到数据: %d, %.2f\n", a, b);
        fclose(file);
    }
    
  • fputc:写入一个字符到文件。

    • 语法
    int fputc(int c, FILE *stream);
    
    • 示例:写入单个字符
    FILE *file = fopen("example.txt", "w");
    if (file != NULL) {
        fputc('A', file);  // 写入字符 'A'
        fclose(file);
    }
    
  • fgetc:从文件中读取一个字符。

    • 语法
    int fgetc(FILE *stream);
    
    • 示例:逐字符读取文件
    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        int ch = fgetc(file);
        printf("读取的字符: %c\n", ch);
        fclose(file);
    }
    
3.2 文本文件与二进制文件的操作

C语言可以处理文本文件二进制文件,它们的区别在于数据存储和处理方式。

  • 文本文件:文件内容以字符形式存储,每个字符占用一个字节,数据存储通常为人可读的格式。
    • 通过 fopen 以文本模式打开(如 "r""w" 等)。
    • 读取操作通常是以行或字符的形式进行。
  • 二进制文件:文件内容存储为原始二进制数据,通常不容易直接由人阅读。
    • 通过 fopen 以二进制模式打开(如 "rb""wb" 等)。
    • 读取操作通常是以二进制块的形式进行,常用于存储结构化数据(如图像、音频、数据库文件等)。

文本文件操作示例

FILE *file = fopen("textfile.txt", "w");
if (file != NULL) {
    fprintf(file, "This is a text file.\n");
    fclose(file);
}

二进制文件操作示例

FILE *file = fopen("binaryfile.bin", "wb");
if (file != NULL) {
    int data[] = {1, 2, 3, 4};
    fwrite(data, sizeof(int), 4, file);  // 写入整数数组
    fclose(file);
}
3.3 文件指针与文件定位

文件指针用于指示文件中的当前位置,C语言提供了一些函数来获取和设置文件指针的位置。

  • ftell:获取文件指针的当前位置,返回一个long类型值,表示文件中的字节数。

    语法

    long ftell(FILE *stream);
    

    示例代码

    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        fseek(file, 0, SEEK_END);  // 移动到文件末尾
        long position = ftell(file);  // 获取文件指针位置
        // 获取文件大小
        printf("文件大小: %ld bytes\n", position);
        fclose(file);
    }
    

    //注: 对于获取文件大小等信息,不一定要打开文件

    #include <stdio.h>
    #include <sys/stat.h>
    
    int main() {
        const char *filename = "example.txt";  // 文件名
        struct stat fileStat;  // 用来存储文件信息
    
        // 获取文件的状态信息
        if (stat(filename, &fileStat) == -1) {
            perror("stat");  // 打印错误信息
            return 1;
        }
    
        // 打印文件大小
        printf("File size: %lld bytes\n", (long long)fileStat.st_size);
    
        return 0;
    }
    
  • fseek:设置文件指针的位置。

    语法

    int fseek(FILE *stream, long offset, int whence);
    
    • offset:相对当前位置的偏移量。
    • whence:指定偏移量的参考位置,常见值有:
      • SEEK_SET:从文件开头开始偏移。
      • SEEK_CUR:从当前文件指针位置偏移。
      • SEEK_END:从文件末尾开始偏移。

    示例代码

    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        fseek(file, 10, SEEK_SET);  // 移动文件指针到文件开头的第10个字节
        char ch = fgetc(file);  // 读取当前位置的字符
        printf("当前位置字符: %c\n", ch);
        fclose(file);
    }
    
  • rewind:将文件指针移到文件开头,相当于fseek(file, 0, SEEK_SET)

    语法

    void rewind(FILE *stream);
    
3.4 错误处理:feof、ferror

C语言提供了两种函数来检查文件操作中的错误或是否到达文件末尾:

  • feof:检测文件是否已到达末尾。返回非零值表示文件结束,返回零表示文件未到达末尾。

    语法

    int feof(FILE *stream);
    

    示例代码

    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        char ch;
        while ((ch = fgetc(file)) != EOF) {  // 读取直到文件末尾
            putchar(ch);
        }
        if (feof(file)) {
            printf("\n文件读取结束。\n");
        }
        fclose(file);
    }
    
  • ferror:检查文件操作是否出错。返回非零值表示发生错误,返回零表示没有错误。

    语法

    int ferror(FILE *stream);
    

    示例代码

    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        if (ferror(file)) {
            printf("文件错误发生!\n");
        }
        fclose(file);
    }
    
  • clearerr:清除文件流的错误标志和文件末尾标志。

    • 语法
    void clearerr(FILE *stream);
    
    • 示例:清除文件流的错误标志
    FILE *file = fopen("example.txt", "r");
    if (file != NULL) {
        // 进行文件读取
        if (ferror(file)) {
            clearerr(file);  // 清除错误标志
        }
        fclose(file);
    }
    

注意,清除错误标志 并不是清空缓冲区,对于scanf等函数读取错误,需要使用getchar清空缓冲区才有效。

while (getchar() != ‘\n’ && getchar() != EOF);

3.5 文件模式

文件打开时的模式决定了文件的访问权限(只读、只写、追加等)。常见的模式包括:

  • r:只读模式,文件必须存在。
  • w:写模式,若文件存在则清空文件内容,若文件不存在则创建。
  • a:追加

模式,文件若不存在则创建,若存在则从文件末尾开始写入。

  • rb:以二进制模式只读打开文件。
  • wb:以二进制模式写入文件。
  • r+:读写模式,文件必须存在。
  • w+:读写模式,文件存在则清空,文件不存在则创建。
  • a+:读写模式,文件末尾追加,文件若不存在则创建。
3.6 文件与目录操作

除了标准的文件读写操作外,C语言还支持一些操作文件和目录的函数,常用于文件系统管理。

  • rename:重命名文件。

    • 语法
    int rename(const char *oldname, const char *newname);
    
    • 示例
    int result = rename("oldfile.txt", "newfile.txt");
    if (result == 0) {
        printf("文件重命名成功!\n");
    } else {
        printf("文件重命名失败!\n");
    }
    
  • remove:删除文件。

    • 语法
    int remove(const char *filename);
    
    • 示例
    int result = remove("example.txt");
    if (result == 0) {
        printf("文件删除成功!\n");
    } else {
        printf("文件删除失败!\n");
    }
    
  • tmpfile:创建一个临时文件并返回文件指针。该文件在程序结束时自动删除。

    • 语法
    FILE *tmpfile(void);
    
    • 示例
    FILE *file = tmpfile();
    if (file != NULL) {
        fprintf(file, "临时文件内容\n");
        fclose(file);
    }
    
3.7 其他文件操作函数
  • setvbuf:设置文件流的缓冲区模式(全缓冲、行缓冲、无缓冲)。

    • 语法
    int setvbuf(FILE *stream, char *buffer, int mode, size_t size);
    
    • 示例
    char buf[1024];
    FILE *file = fopen("example.txt", "w");
    setvbuf(file, buf, _IOFBF, sizeof(buf));  // 设置全缓冲
    fprintf(file, "使用缓冲区写入数据。\n");
    fclose(file);
    
  • fflush:刷新文件流的缓冲区,确保所有数据被写入文件。(非标准)

    • 语法
    int fflush(FILE *stream);
    
    • 示例
    FILE *file = fopen("example.txt", "w");
    fprintf(file, "数据写入文件\n");fflush(file);  // 强制刷新缓冲区fclose(file);
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值