C 语言文件 IO 学习Day03:从基础函数到实战踩坑(BMP 读取 + 词典查询)
本文为 C 语言软件编程学习 Day03 笔记系统梳理标准 IO 库函数、核心易混点对比并结合「BMP 图片宽高读取」「英汉词典查询」两个实战项目总结实操中高频踩坑点文章目录前言一、文件 IO 核心函数全解1. fgetc读取单个字符2. fputs写入字符串3. fgets读取一行字符串4. fprintf格式化写入文件5. fwrite整块数据写入6. fread整块数据读取7. fseek设置文件偏移位置8. ftell获取当前偏移量9. rewind回到文件开头二、易混函数深度对比1. gets 与 fgets 核心区别2. puts 与 fputs 核心区别三、实战项目与踩坑复盘项目 1读取 24 位 BMP 图片的宽度和高度项目 2英汉词典查询系统四、高频易错点速查表五、课后练习文件拷贝前言第三天的学习核心围绕标准文件 IO 操作展开从单字符读写到整块数据读写再到文件位置偏移控制最终落地到两个实战场景。这部分知识点函数多、细节碎坑点密集尤其字符串与指针结合的地方非常容易出错。本文按「函数大全 → 易混对比 → 实战项目 → 易错汇总」的结构整理方便复习和避坑。一、文件 IO 核心函数全解1. fgetc读取单个字符int fgetc(FILE *stream);功能从文件流中读取一个字符返回值成功返回字符的 ASCII 码值失败或读到文件末尾返回EOF注意返回值用int接收而不是char因为EOF是超出 char 范围的负值2. fputs写入字符串int fputs(const char *s, FILE *stream);功能将字符串写入指定文件流返回值成功返回非负整数失败返回EOF特点不会自动追加换行符\n原样输出字符串内容3. fgets读取一行字符串char *fgets(char *s, int size, FILE *stream);功能从流中读取一行字符串最多读取size-1个字符末尾自动补\0返回值成功返回缓冲区首地址失败或读到文件末尾返回NULL核心特点自带长度保护不会缓冲区溢出会保留行尾的换行符\n不会自动丢弃既可读取标准输入stdin也可读取普通文件4. fprintf格式化写入文件int fprintf(FILE *stream, const char *format, ...);功能按格式化字符串将数据写入指定文件流返回值成功返回实际写入的字符个数失败返回负数对比printf等价于fprintf(stdin, ...)只是默认输出到终端5. fwrite整块数据写入size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream);功能向文件写入nmemb个对象每个对象占size字节参数ptr待写入数据的内存首地址size单个对象的字节大小nmemb要写入的对象数量返回值成功返回实际写入的完整对象个数失败返回 06. fread整块数据读取size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);功能从文件中读取nmemb个对象每个对象占size字节存入 ptr 指向的内存返回值成功返回实际读到的完整对象个数失败或读到文件末尾返回 0两种常用写法读单个结构体 / 整数fread(var, sizeof(var), 1, fp)→ 返回值判断是否等于 1读字节缓冲区fread(buf, 1, sizeof(buf), fp)→ 返回值就是读到的字节数7. fseek设置文件偏移位置int fseek(FILE *stream, long offset, int whence);功能重新定位文件读写光标的位置基准参数 whenceSEEK_SET从文件开头计算偏移SEEK_CUR从当前光标位置计算偏移SEEK_END从文件末尾计算偏移返回值成功返回 0失败返回 - 18. ftell获取当前偏移量long ftell(FILE *stream);功能获取当前光标距离文件开头的字节偏移量经典用法配合 fseek 获取文件总大小fseek(fp, 0, SEEK_END); long file_size ftell(fp);9. rewind回到文件开头void rewind(FILE *stream);功能将文件光标直接重置到文件开头等价于fseek(fp, 0, SEEK_SET);二、易混函数深度对比1. gets 与 fgets 核心区别这是考试最高频考点也是实操最容易踩坑的点。表格对比维度gets()fgets()缓冲区长度无长度检查输入多长写多长强制指定 size最多读 size-1 个字符溢出风险极高C11 标准已正式删除安全不会越界换行符处理读到换行直接丢弃替换为\0换行符保留在字符串中再补\0读取来源只能从标准输入读取可从任意文件流读取推荐程度禁止使用标准推荐写法踩坑提醒用fgets从键盘读取单词后直接和文件内单词做strcmp会永远失败因为字符串末尾多了一个\n。必须先清除换行符str[strcspn(str, \n)] \0;2. puts 与 fputs 核心区别表格对比维度puts()fputs()换行符自动在末尾追加一个\n不会额外添加任何字符原样输出输出目标只能输出到标准输出可输出到任意文件流三、实战项目与踩坑复盘项目 1读取 24 位 BMP 图片的宽度和高度需求从 BMP 文件中读取图片分辨率已知宽度在文件偏移 18 字节处占 4 字节高度在偏移 22 字节处占 4 字节。核心代码#include stdio.h int main(void) { FILE *fp fopen(src.bmp, rb); // 二进制文件必须用rb打开 if (NULL fp) { perror(fopen failed); return -1; } unsigned int width 0, height 0; fseek(fp, 18, SEEK_SET); // 定位到宽度字段 fread(width, 4, 1, fp); fread(height, 4, 1, fp); // 读完宽度光标自动后移4字节正好对准高度 printf(宽度%u\n高度%u\n, width, height); fclose(fp); return 0; }高频踩坑点偏移计算错误误以为宽度从 17 字节开始正确逻辑文件头占 14 字节0-13 biSize 占 4 字节14-17 18宽度从 18 号字节开始。字段占 N 字节下一字段起始位置 起始偏移 N。用文本模式打开二进制文件BMP 是二进制文件必须用rb模式否则数据会错乱。小端序问题BMP 采用小端存储x86/x64CPU 原生小端直接 fread 到 int 变量即可无需手动翻转字节。项目 2英汉词典查询系统需求终端输入单词从词典文件每行格式单词 释义释义内部含空格中匹配并打印对应释义。正确实现strtok 指针遍历#include stdio.h #include string.h int main(void) { FILE *fp fopen(dict.txt, r); if (NULL fp) { perror(fopen failed); return -1; } char str[100] {0}; char tmpbuff[4096] {0}; gets(str); // 仅作业演示使用实际开发禁用gets while (fgets(tmpbuff, sizeof(tmpbuff), fp) ! NULL) { // 第一步strtok只调用一次切出第一个单词 char *word strtok(tmpbuff, ); if (word NULL) continue; // 第二步遍历指针越过单词末尾的\0找到释义区域 char *meaning word; while (*meaning ! \0) meaning; // 走到单词结尾 meaning; // 跨过strtok写入的\0 // 第三步跳过释义开头连续的空格 while (*meaning ! \0 *meaning ) { meaning; } // 第四步字符串比较必须用strcmp if (strcmp(str, word) 0) { printf(含义为%s, meaning); break; } } fclose(fp); return 0; }踩坑大汇总低级错误文件名加双引号fopen(argv[1], r); // ❌ 去找名叫argv[1]的文件永远打开失败 fopen(argv[1], r); // ✅ 正确访问命令行参数致命错误用比较字符串比较的是指针地址不是字符串内容。内容比较必须用strcmp相等返回 0。经典错误多次调用 strtok 切碎释义strtok(NULL, )会把释义内部的空格也当分隔符切开只能拿到半截释义。正确做法是只调用一次 strtok 切单词剩余内容靠指针遍历获取。隐形错误fgets 带换行符输入单词和词典行尾都可能带\n不处理会导致 strcmp 永远匹配失败。四、高频易错点速查表易错点错误写法正确写法字符串比较if(str1 str2)if(strcmp(str1, str2) 0)命令行参数传文件名fopen(argv[1],r)fopen(argv[1],r)二进制文件打开fopen(a.bmp,r)fopen(a.bmp,rb)gets 安全问题gets(str)fgets(str, sizeof(str), stdin)fgets 换行符直接拿去 strcmp先str[strcspn(str,\n)]\0strtok 切释义strtok(NULL, )只切一次单词剩余内容指针遍历BMP 偏移计算宽度偏移 17宽度偏移 18ftell 返回值%d打印%ld打印long 类型指针遍历边界先判断字符再判断 \0先判断!\0再判断字符利用短路保护五、课后练习文件拷贝利用fread和fwrite实现二进制文件拷贝图片、文档均可核心框架#include stdio.h int main(int argc, char *argv[]) { if (argc 3) { printf(usage: ./a.out src_file dst_file\n); return -1; } FILE *fp_src fopen(argv[1], rb); FILE *fp_dst fopen(argv[2], wb); char buf[4096] {0}; size_t n 0; while ((n fread(buf, 1, sizeof(buf), fp_src)) 0) { fwrite(buf, 1, n, fp_dst); } fclose(fp_src); fclose(fp_dst); return 0; }

相关新闻

【研发类-AI和ML开发Skills】ai-dev-jobs-mcp 技能

【研发类-AI和ML开发Skills】ai-dev-jobs-mcp 技能

通过AI Dev Jobs MCP搜索8,400个AI和ML职位,覆盖489家公司,检查列表和雇主信息,匹配角色,查看薪资和市场统计数据。 技能概述 ai-dev-jobs-mcp 技能是一个远程MCP服务器,为AI智能体提供AI和ML职位列表的实时索引访问…

2026/11/14 6:30:08 阅读更多 →
edge网页遇到打不开--Internet Explorer 兼容性/急速/高速模式/旧网络设备网页无法访问

edge网页遇到打不开--Internet Explorer 兼容性/急速/高速模式/旧网络设备网页无法访问

internet属性勾选这三个IE兼容性问题Internet Explorer 模式页面这些页面将从你添加的那天起在 Internet Explorer 模式下打开 30 天. 你有 1 个页面将在 Internet Explorer 模式下自动打开将网址添加后,被添加的网址后续在打开时,会以Internet Explorer…

2026/10/18 23:36:32 阅读更多 →
AI一套数学卷子,乱码了怎么办?让“AI导出鸭”把LaTeX公式从“天书”还原为可编辑文档

AI一套数学卷子,乱码了怎么办?让“AI导出鸭”把LaTeX公式从“天书”还原为可编辑文档

AI一套数学卷子,乱码了怎么办?让“AI导出鸭”把LaTeX公式从“天书”还原为可编辑文档 如果你曾试图把AI生成的一套数学卷子直接复制到Word或PDF里,大概率见过这样的场面:积分符号变成了“銝”,分数线的上下标错位堆叠&…

2026/10/21 10:17:00 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/14 5:13:29 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/14 5:13:29 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/14 5:13:29 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/13 22:08:41 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/14 2:41:37 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/14 5:13:29 阅读更多 →

日新闻

周新闻

月新闻