当前位置:首页 > 技术 > 正文内容

C语言文件I/O操作完全指南

访客 技术 2026年5月24日 3

文件的本质与分类

在操作系统层面,文件是存储于磁盘等持久化介质上的数据集合,涵盖文本、图像、可执行程序等多种形态。通过文件机制,程序能够实现数据的长期保存与跨会话访问。

依据编码方式差异,文件划分为两大类别:

  • 文本文件:数据以ASCII字符形式存储,人类可直接阅读
  • 二进制文件:数据按内存原样直接写入,无格式转换

需特别注意:数值型数据可选择两种存储形式,而字符型数据在外存中仅能采用ASCII编码。

流机制与标准通道

C语言通过"流"抽象统一了不同设备的I/O操作。流可理解为字节序列的传输通道,程序借助流与外部世界交互,无需关注底层设备差异。

程序启动时,系统默认开启三个标准流:

流名称功能典型应用
stdin标准输入scanf, getchar
stdout标准输出printf, putchar
stderr标准错误perror

文件操作需显式创建文件流,通过FILE*类型指针关联具体的文件信息区。

文件操作核心流程

所有文件操作遵循固定范式:

  1. 打开文件 → 建立流连接
  2. 执行读写 → 数据传输
  3. 关闭文件 → 释放资源

基础代码框架

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>

int main(void)
{
    FILE* handle = fopen("data.txt", "r");
    if (!handle) {
        perror("文件打开失败");
        return 1;
    }
    
    /* 读写操作区域 */
    
    fclose(handle);
    handle = NULL;
    return 0;
}

文件的打开与关闭

fopen函数

函数原型:FILE* fopen(const char* path, const char* mode);

路径说明:

  • 绝对路径:从根目录开始的完整定位,如/home/user/doc.txtC:\Users\doc.txt
  • 相对路径:相对于当前工作目录,如./config.ini或直接写文件名

常用打开模式:

模式含义文件不存在时
"r"只读文本失败
"w"只写文本(覆盖)创建新文件
"a"追加文本创建新文件
"r+"读写文本失败
"w+"读写文本(覆盖)创建新文件
"rb"/"wb"/"ab"二进制对应模式同上

fclose函数

函数原型:int fclose(FILE* stream);

成功返回0,失败返回非零值。关闭后应立即将指针置空,避免野指针风险。

顺序读写操作

函数功能描述适用范围
fgetc单字符输入所有输入流
fputc单字符输出所有输出流
fgets字符串输入所有输入流
fputs字符串输出所有输出流
fscanf格式化输入所有输入流
fprintf格式化输出所有输出流
fread二进制块读取仅文件流
fwrite二进制块写入仅文件流

字符级操作:fgetc与fputc

/* 逐字符读取文件内容 */
int symbol;
while ((symbol = fgetc(handle)) != EOF) {
    putchar(symbol);
}

/* 向文件写入字符序列 */
fputc('H', handle);
fputc('i', handle);

字符串操作:fgets与fputs

fgets(buffer, size, stream)最多读取size-1个字符,自动补'\0',遇换行符或EOF停止。

char buffer[128];
while (fgets(buffer, sizeof(buffer), handle)) {
    printf("%s", buffer);  /* 包含读取的换行符 */
}

fputs不会自动添加换行,需手动控制格式:

fputs("第一行内容\n", handle);
fputs("第二行内容\n", handle);

格式化I/O:fscanf与fprintf

typedef struct {
    char id[16];
    int quantity;
    double price;
} Product;

/* 写入结构化数据 */
Product item = {"A-2024-001", 150, 29.99};
fprintf(handle, "%s %d %.2f\n", item.id, item.quantity, item.price);

/* 读取结构化数据 */
Product temp;
fscanf(handle, "%s %d %lf", temp.id, &temp.quantity, &temp.price);

二进制块操作:fread与fwrite

适用于结构体数组等复杂数据的直接持久化:

/* 写入整数数组 */
int dataset[] = {10, 20, 30, 40, 50};
size_t written = fwrite(dataset, sizeof(int), 5, handle);

/* 读取到结构体数组 */
Product inventory[100];
size_t loaded = fread(inventory, sizeof(Product), 100, handle);

随机位置访问

fseek定位函数

原型:int fseek(FILE* stream, long offset, int origin);

起始位置选项:

  • SEEK_SET:文件开头(偏移量≥0)
  • SEEK_CUR:当前位置(偏移量可正可负)
  • SEEK_END:文件末尾(偏移量≤0)
/* 跳转到文件第20字节处 */
fseek(handle, 20, SEEK_SET);

/* 回退10字节 */
fseek(handle, -10, SEEK_CUR);

/* 定位到倒数第5字节 */
fseek(handle, -5, SEEK_END);

ftell获取位置

/* 计算文件总大小 */
fseek(handle, 0, SEEK_END);
long filesize = ftell(handle);
rewind(handle);  /* 回到开头 */

rewind重置位置

rewind(handle)等价于fseek(handle, 0, SEEK_SET),但更简洁且清除错误标志。

读取结束判定

区分读取结束原因至关重要:

函数类型结束标志后续检测
fgetc返回EOFfeof区分错误/正常结束
fgets返回NULL同上
fread返回值<请求数feof/ferror判断原因

feof(FILE*)仅在读取操作返回结束后有效,用于确认是否因到达文件尾而终止,而非读取错误。

标签: C语言

相关文章

Linux crontab 详解

1) crontab 是什么cron 是 Linux 的定时任务守护进程;crontab 是用来编辑/查看“按时间周期执行命令”的表(cron table)。常见两类:用户 crontab:每个用户一份(crontab -e 编辑)系统级 crontab / cron.d:可指定执行用户(/etc/crontab、/etc/cron.d/*)2) crontab 时间...

富文本里可以允许的 HTML 属性

一、所有标签默认允许的安全属性(极少)class        (可选)id           (通常建议禁用)title️ 注意:id 容易被滥用做锚点注入,很多系统直接禁用class 允许的话最好只允许固定前缀(如 editor-*)二、a 标签允许属性<a href="" t...

Mac 安装 Node.js 指南

方法一:通过官网安装包(最简单,适合初学者)如果你只是想快速安装并开始使用,这是最直接的方法。访问 Node.js 官网。页面会显示两个版本:LTS (Recommended For Most Users):长期支持版,最稳定。建议选这个。Current:最新特性版,包含最新功能但可能不够稳定。下载 .pkg 安装包并运行。按照安装向导点击“下一步”即可完成。方法二:使用 Homebrew 安装(...

Dom\HTML_NO_DEFAULT_NS 的副作用:自动加闭合标签

在使用Dom\HTMLDocument时,Dom\HTML_NO_DEFAULT_NS 将禁止在解析过程中设置元素的命名空间, 此设置是为了与DOMDocument向后兼容而存在的。当使用它时,已知的一个副作用就是:自动加闭合标签例如 </img> 为什么会这样?当你使用:Dom\HTML_NO_DEFAULT_NS文档会变成 无命名空间模式,此时内部更接近 XML...

Laravel 事件和监听器创建

在 Laravel 中,使用 Artisan 命令创建 Events(事件) 和 Listeners(监听器) 是非常高效的。你可以通过以下几种方式来实现:1. 手动创建单个 Event如果你只想创建一个事件类,可以使用 make:event 命令:Bashphp artisan make:event UserRegistered执行后,文件将生成在 app/Even...

自定义域名解析神器 dnsmasq

什么是 dnsmasq?dnsmasq 是一个轻量级、功能强大的网络服务工具,专为小型和中等规模网络设计。它是一个综合的网络基础设施解决方案[1]。dnsmasq 能做什么?功能说明应用场景DNS 转发与缓存将 DNS 查询转发到上游服务器(ISP、Google DNS 等),并在本地缓存结果加快 DNS 查询速度,减少外部 DNS 流量本地 DNS解析本地网络设备的主机名,无需编辑&n...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。