C语言filedate如何获取与处理文件日期?

99ANYc3cd6
预计阅读时长 23 分钟
位置: 首页 C语言 正文

所有的文件操作(无论是文本文件还是二进制文件)都被看作是一个连续的字节流。 程序通过一个指向这个流的指针(FILE* 类型)来读写数据。

c语言filedate
(图片来源网络,侵删)

核心概念:文件指针 (FILE*)

在 C 语言中,你不会直接操作文件本身,而是通过一个叫做文件指针 (FILE*) 的对象来间接操作,这个指针指向一个包含了文件相关信息(如文件位置、缓冲区等)的结构体。

你可以把它想象成遥控器,你通过遥控器(文件指针)来控制电视(文件),而不是直接去操作电视内部的电路。


基本文件操作步骤

一个完整的文件操作流程通常分为以下几步:

  1. 打开文件 (fopen)
  2. 读写文件 (fread, fwrite, fgetc, fputc, fgets, fputs, fprintf, fscanf 等)
  3. 关闭文件 (fclose)

重要提示:每次文件操作后,尤其是写操作后,一定要记得关闭文件,这不仅能释放系统资源,还能确保所有缓冲区中的数据都被真正写入到磁盘文件中。

c语言filedate
(图片来源网络,侵删)

核心函数详解

打开文件:fopen

fopen 函数用于打开一个文件,并返回一个指向该文件的 FILE 指针。

函数原型:

FILE *fopen(const char *filename, const char *mode);
  • filename: 字符串,表示要打开的文件名(可以包含路径,如 "C:/data/myfile.txt")。
  • mode: 字符串,指定文件的打开模式。

常用打开模式:

模式 含义 如果文件不存在 如果文件存在
"r" 只读 失败 打开成功,文件指针指向开头
"w" 只写 创建新文件 清空文件内容,文件指针指向开头
"a" 追加 创建新文件 打开成功,文件指针指向末尾
"r+" 读写 失败 打开成功,文件指针指向开头
"w+" 读写 创建新文件 清空文件内容,文件指针指向开头
"a+" 读写 创建新文件 打开成功,文件指针指向末尾

附加字符:

c语言filedate
(图片来源网络,侵删)
  • "b": 以二进制模式打开。"rb", "wb+",在 Windows 系统上区分文本和二进制模式很重要,而在 Linux/macOS 上则影响不大。

返回值:

  • 成功:返回一个指向 FILE 结构体的指针。
  • 失败:返回 NULL指针。

示例:

FILE *fp;
fp = fopen("data.txt", "w"); // 以只写模式打开 data.txt,如果不存在则创建
if (fp == NULL) {
    printf("无法打开文件!\n");
    // 处理错误
}

关闭文件:fclose

fclose 函数用于关闭一个已经打开的文件,释放相关的资源。

函数原型:

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

返回值:

  • 成功:返回 0
  • 失败:返回 EOF (通常是一个宏定义为 -1)。

示例:

if (fclose(fp) != 0) {
    printf("关闭文件时出错!\n");
}

写入文件

a) 写入单个字符:fputc

int fputc(int c, FILE *stream);
// 将字符 c 写入到 stream 指向的文件中。
// 成功返回写入的字符,失败返回 EOF。

b) 写入字符串:fputs

int fputs(const char *str, FILE *stream);
// 将字符串 str 写入到 stream 中(不写入字符串结束符 '\0')。
// 成功返回非负值,失败返回 EOF。

c) 格式化写入:fprintf

int fprintf(FILE *stream, const char *format, ...);
// 按照 format 指定的格式,将数据写入 stream 中。
// 用法与 printf 类似,只是第一个参数是文件指针。

写入示例:

FILE *fp = fopen("output.txt", "w");
if (fp != NULL) {
    fputc('A', fp);
    fputs("Hello, World!\n", fp);
    fprintf(fp, "The value of pi is approximately %.2f\n", 3.14159);
    fclose(fp);
}
// output.txt 的内容将是:
// AHello, World!
// The value of pi is approximately 3.14

读取文件

a) 读取单个字符:fgetc

int fgetc(FILE *stream);
// 从 stream 中读取一个字符,并返回该字符的 ASCII 值。
// 如果读到文件末尾或出错,返回 EOF。

b) 读取一行:fgets

char *fgets(char *str, int n, FILE *stream);
// 从 stream 中读取一行,最多读取 n-1 个字符,并存入 str 中。
// 会在末尾自动添加 '\0',如果读取了换行符,也会包含在 str 中。
// 成功返回 str,失败或到文件末尾返回 NULL。

c) 格式化读取:fscanf

int fscanf(FILE *stream, const char *format, ...);
// 按照 format 指定的格式,从 stream 中读取数据。
// 用法与 scanf 类似,只是第一个参数是文件指针。

读取示例:

FILE *fp = fopen("output.txt", "r");
if (fp != NULL) {
    char ch;
    char line[100];
    int num;
    // 使用 fgetc 逐个字符读取
    printf("逐个字符读取:\n");
    while ((ch = fgetc(fp)) != EOF) {
        putchar(ch);
    }
    printf("\n\n");
    // 需要重置文件指针到开头才能再次读取
    rewind(fp); // 或者 fseek(fp, 0, SEEK_SET);
    // 使用 fgets 读取一行
    printf("使用 fgets 读取一行:\n");
    fgets(line, sizeof(line), fp);
    printf("读取到: %s", line);
    // 重置文件指针
    rewind(fp);
    // 使用 fscanf 读取格式化数据
    printf("\n使用 fscanf 读取数据:\n");
    // 注意:fscanf 会从当前位置开始扫描,可能会跳过空白字符
    // 为了找到浮点数,我们可能需要调整逻辑或移动指针
    rewind(fp);
    while (fscanf(fp, "%f", &num) == 1) {
        printf("读取到浮点数: %f\n", num);
    }
    fclose(fp);
}

二进制文件读写

对于结构体等复杂数据,使用二进制模式更高效。

a) 写入一块数据:fwrite

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);
// ptr: 指向要写入数据的内存块的指针。
// size: 每个数据项的大小(字节)。
// nmemb: 要写入的数据项的数量。
// stream: 文件指针。
// 返回成功写入的数据项的数量。

b) 读取一块数据:fread

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
// ptr: 指向存储读取数据的内存块的指针。
// size: 每个数据项的大小(字节)。
// nmemb: 要读取的数据项的数量。
// stream: 文件指针。
// 返回成功读取的数据项的数量。

二进制读写示例:

#include <stdio.h>
#include <string.h>
typedef struct {
    int id;
    char name[50];
    float score;
} Student;
int main() {
    Student s1 = {101, "Zhang San", 95.5};
    Student s2;
    // 写入结构体到二进制文件
    FILE *fp_bin = fopen("students.dat", "wb");
    if (fp_bin) {
        fwrite(&s1, sizeof(Student), 1, fp_bin);
        fclose(fp_bin);
        printf("结构体 s1 已写入 students.dat\n");
    }
    // 从二进制文件读取结构体
    fp_bin = fopen("students.dat", "rb");
    if (fp_bin) {
        fread(&s2, sizeof(Student), 1, fp_bin);
        fclose(fp_bin);
        printf("从文件读取的结构体信息:\n");
        printf("ID: %d, Name: %s, Score: %.2f\n", s2.id, s2.name, s2.score);
    }
    return 0;
}

文件指针定位

  • rewind(fp): 将文件指针重置到文件开头,等价于 fseek(fp, 0, SEEK_SET)
  • fseek(fp, offset, whence):
    • offset: 偏移量(字节)。
    • whence: 起始位置。
      • SEEK_SET (0): 从文件开头开始计算。
      • SEEK_CUR (1): 从当前位置开始计算。
      • SEEK_END (2): 从文件末尾开始计算。
    • 示例:fseek(fp, 20, SEEK_SET); // 将指针移动到文件开头后的第20个字节。
  • ftell(fp): 返回当前文件指针的位置(相对于文件开头的字节数)。

错误处理

文件操作可能会因为各种原因失败(如文件不存在、磁盘已满、没有权限等),进行错误检查至关重要。

最佳实践:

  1. 检查 fopen 的返回值:永远不要假设文件打开成功。
  2. 检查 fread/fwrite 的返回值:它们可能返回比你期望的少的数量。
  3. 使用 feofferror:
    • int feof(FILE *stream): 检查文件指针是否到达了文件末尾。
    • int ferror(FILE *stream): 检查文件操作过程中是否发生了错误。

错误处理示例:

FILE *fp = fopen("non_existent_file.txt", "r");
if (fp == NULL) {
    perror("打开文件失败"); // perror 会打印 "打开文件失败: " 并附上系统错误信息
    // exit(EXIT_FAILURE); // 可以选择退出程序
}
int ch;
while ((ch = fgetc(fp)) != EOF) {
    // ... 处理字符 ...
}
if (ferror(fp)) {
    printf("读取文件时发生错误!\n");
} else if (feof(fp)) {
    printf("成功到达文件末尾,\n");
}
fclose(fp);

操作 函数 说明
打开 fopen() 返回 FILE*,失败返回 NULL
关闭 fclose() 释放资源,成功返回 0
fputc() 写一个字符
fputs() 写一个字符串
fprintf() 格式化写入
fwrite() 二进制块写入
fgetc() 读一个字符
fgets() 读一行
fscanf() 格式化读取
fread() 二进制块读取
定位 fseek() 移动文件指针
ftell() 获取当前指针位置
rewind() 重置指针到开头
检查 feof() 检查是否到文件末尾
ferror() 检查是否发生错误
perror() 打印系统错误信息

掌握了这些核心函数和概念,你就可以在 C 语言中进行各种复杂的文件操作了。检查返回值是稳健编程的关键。

-- 展开阅读全文 --
头像
C语言keyboard是什么?如何使用?
« 上一篇 04-13
dede如何更改模板路径?
下一篇 » 04-13

相关文章

取消
微信二维码
支付宝二维码

目录[+]