当前位置: 首页 > news >正文

C语言文件操作完全指南:从基础到实践

C语言文件操作完全指南

1. 文件操作基础概念

C语言将文件视为一个字符(字节)序列,由一个个字符(字节)数据顺序组成。根据数据组织形式可分为:

  • ASCII文件:以字符形式存储,便于阅读和编辑
  • 二进制文件:以二进制形式存储,节省空间且处理效率高

标准文件操作包括:打开、关闭、读写、状态检查以及定位等。

2. 文件打开与关闭

2.1 文件打开函数

FILE *fopen(char *pname, char *mode);

功能说明

  • 按照mode规定方式打开pname指定的文件
  • 若文件不存在:
    • 写模式(mode包含'w'):创建新文件
    • 读模式(mode包含'r'):返回错误

参数说明

  • pname:要打开的文件名字符串
  • mode:文件处理方式字符串,常见模式:
    • "r":只读
    • "w":只写(创建新文件或清空已有)
    • "a":追加
    • "r+":读写(文件必须存在)
    • "w+":读写(创建新文件或清空已有)
    • "a+":读写(追加模式)

返回值

  • 成功:返回文件指针
  • 失败:返回NULL

示例

FILE *fp; if((fp=fopen("test", "r")) == NULL) { printf("The file can not be opened.\n"); exit(1); }

2.2 标准设备文件

C语言将输入输出设备视为文件:

  • 标准输入(stdin):键盘
  • 标准输出(stdout):屏幕
  • 标准错误(stderr):错误输出

程序启动时自动打开这三个文件。

2.3 文件关闭函数

int fclose(FILE *fp);

功能说明

  • 关闭fp指向的文件
  • 释放文件结构体变量
  • 返回操作结果

参数说明

  • fp:已打开文件的指针

返回值

  • 成功:0
  • 失败:EOF

示例

int n = fclose(fp);

3. 文件读写操作

3.1 字符读写

3.1.1 读取字符
int fgetc(FILE *fp);

示例:显示文件内容

#include <stdio.h> void main(int argc, char *argv[]) { int ch; FILE *fp; if(argc != 2) { printf("Error format,Usage: display filename1\n"); return; } if((fp=fopen(argv[1], "r")) == NULL) { printf("The file <%s> can not be opened.\n", argv[1]); return; } ch = fgetc(fp); while(ch != EOF) { putchar(ch); ch = fgetc(fp); } fclose(fp); }
3.1.2 写入字符
int fputc(int ch, FILE *fp);

示例:文件复制

#include <stdio.h> void main(int argc, char *argv[]) { int ch; FILE *in, *out; if(argc != 3) { printf("Error in format,Usage: copyfile filename1 filename2\n"); return; } if((in=fopen(argv[1], "r")) == NULL) { printf("The file <%s> can not be opened.\n", argv[1]); return; } if((out=fopen(argv[2], "w")) == NULL) { printf("The file %s can not be opened.\n", argv[2]); return; } ch = fgetc(in); while(ch != EOF) { fputc(ch, out); ch = fgetc(in); } fclose(in); fclose(out); }

3.2 字符串读写

3.2.1 读取字符串
char *fgets(char *str, int n, FILE *fp);
3.2.2 写入字符串
int fputs(char *str, FILE *fp);

示例:文件内容附加

#include <stdio.h> #define SIZE 512 void main(int argc, char *argv[]) { char buffer[SIZE]; FILE *fp1, *fp2; if(argc != 3) { printf("Usage: linkfile filename1 filename2\n"); return; } if((fp1=fopen(argv[1], "a")) == NULL) { printf("The file %s can not be opened.\n", argv[1]); return; } if((fp2=fopen(argv[2], "r")) == NULL) { printf("The file %s can not be opened.\n", argv[2]); return; } while(fgets(buffer, SIZE, fp1) != NULL) printf("%s\n", buffer); while(fgets(buffer, SIZE, fp2) != NULL) fputs(buffer, fp1); fclose(fp1); fclose(fp2); }

3.3 格式化读写

3.3.1 格式化写入
int fprintf(FILE *fp, char *format, arg_list);
3.3.2 格式化读取
int fscanf(FILE *fp, char *format, arg_list);

示例:学生信息存储

#include <stdio.h> void main() { char name[10]; int nAge, nClass; long number; FILE *fp; if((fp=fopen("student.txt", "w")) == NULL) { printf("The file %s can not be opened.\n", "student.txt"); return; } fscanf(stdin, "%s %d %d %ld", name, &nClass, &nAge, &number); fprintf(fp, "%s %5d %4d %8ld", name, nClass, nAge, number); fclose(fp); if((fp=fopen("student.txt", "r")) == NULL) { printf("The file %s can not be opened.\n", "student.txt"); return; } fscanf(fp, "%s %d %d %ld", name, &nClass, &nAge, &number); printf("name nClass nAge number\n"); fprintf(stdout, "%-10s%-8d%-6d%-8ld\n", name, nClass, nAge, number); fclose(fp); }

3.4 二进制读写

3.4.1 二进制读取
int fread(void *buffer, unsigned size, unsigned count, FILE *fp);
3.4.2 二进制写入
int fwrite(void *buffer, unsigned size, unsigned count, FILE *fp);

示例:结构体文件操作

#include <stdio.h> #define SIZE 4 struct worker { int number; char name[20]; int age; }; void main() { struct worker wk; int n; FILE *in, *out; if((in=fopen("file1.txt", "rb")) == NULL) { printf("The file %s can not be opened.\n", "file1.txt"); return; } if((out=fopen("file2.txt", "wb")) == NULL) { printf("The file %s can not be opened.\n", "file2.txt"); return; } while(fread(&wk, sizeof(struct worker), 1, in) == 1) fwrite(&wk, sizeof(struct worker), 1, out); fclose(in); fclose(out); }

4. 文件状态检查

4.1 文件结束检测

int feof(FILE *fp);

4.2 错误检测

int ferror(FILE *fp);

4.3 清除错误标志

void clearerr(FILE *fp);

4.4 获取当前位置

long ftell(FILE *fp);

示例:带错误处理的文件复制

#include <stdio.h> void main(int argc, char *argv[]) { FILE *in, *out; char ch; if(argc != 3) { printf("Usage: copyfile filename1 filename2\n"); return; } if((in=fopen(argv[1], "rb")) == NULL) { printf("The file %s can not be opened.\n", argv[1]); return; } if((out=fopen(argv[2], "wb")) == NULL) { printf("The file %s can not be opened.\n", argv[2]); return; } while(!feof(in)) { ch = fgetc(in); if(ferror(in)) { printf("read error!\n"); clearerr(in); } else { fputc(ch, out); if(ferror(out)) { printf("write error!\n"); clearerr(out); } } } fclose(in); fclose(out); }

5. 文件定位

5.1 重置文件指针

void rewind(FILE *fp);

5.2 随机定位

int fseek(FILE *fp, long offset, int base);

base参数取值

  • SEEK_SET:文件开头
  • SEEK_CUR:当前位置
  • SEEK_END:文件末尾

示例:随机访问学生记录

#include <stdio.h> #include <string.h> struct std_type { int num; char name[20]; int age; char class; } stud; int cstufile() { int i; FILE *fp; if((fp=fopen("stufile", "wb")) == NULL) { printf("The file can't be opened for write.\n"); return 0; } for(i=1; i<=100; i++) { stud.num = i; strcpy(stud.name, "aaaa"); stud.age = 17; stud.class = '8'; fwrite(&stud, sizeof(struct std_type), 1, fp); } fclose(fp); return 1; } void main() { int n; FILE *fp; if(cstufile() == 0) return; if((fp=fopen("stufile", "rb")) == NULL) { printf("The file can not be opened.\n"); return; } for(n=0; n<100; n+=2) { fseek(fp, n*sizeof(struct std_type), SEEK_SET); fread(&stud, sizeof(struct std_type), 1, fp); printf("%10d%20s%10d%4c\n", stud.num, stud.name, stud.age, stud.class); } fclose(fp); }
http://www.jsqmd.com/news/546184/

相关文章:

  • SmartBMS:革新性开源智能电池管理系统技术解析
  • 开源工具ppInk:提升数字化协作效率的屏幕标注解决方案
  • 从串口通信到内存总线:手把手拆解‘波特率’、‘比特率’与‘总线带宽’的异同与实战计算
  • 【CTF工具】gaps拼图神器:从安装到实战的完整指南
  • STM32 RTC毫秒级计时实战:从寄存器操作到精准时间戳(附完整代码)
  • 网卡bonding性能调优指南:iperf3参数-w和-P的最佳实践组合
  • QGIS 3.28 保姆级配置指南:从中文界面到高德底图,手把手搞定智驾地图工作流
  • 革命性NS模拟器管理工具:让复杂配置成为历史
  • OpCore-Simplify:重新定义黑苹果EFI配置流程的自动化工具
  • 快速体验AI写作魅力:Qwen3-4B模型镜像一键部署,开启智能创作之旅
  • OpenClaw CLI进阶:GLM-4.7-Flash任务批量处理技巧
  • 【PAT甲级真题】- Is It a Binary Search Tree (25)
  • MySQL存储引擎InnoDB与MyISAM详解
  • Mikan Project:终极动漫追番神器,三步打造你的专属追番体验
  • OpenClaw开源贡献指南:为ollama-QwQ-32B编写自定义技能模块
  • Mac本地AI绘画完全指南:用Mochi Diffusion释放创意潜能
  • Linux环境下KingbaseES V8 R6安装与配置全攻略
  • Win11Debloat:释放Windows潜能的系统优化解决方案
  • 5大突破让低配电脑玩转AI绘画:FLUX.1-dev模型优化技术全解析
  • OpenClaw配置备份指南:Qwen3-32B镜像环境快速迁移
  • 告别选择困难:QtCreator写代码,VSCode调AI,我的混合开发效率翻倍秘诀
  • Lobe Theme:为Stable Diffusion WebUI注入现代设计美学的终极界面解决方案
  • Balena Etcher完整指南:5分钟学会安全烧录SD卡和USB设备
  • 【Zynq 进阶一】深度解析 PetaLinux 存储布局:NAND Flash 分区与 DDR 内存分配全攻略
  • MySQL服务启动失败:NET HELPMSG 3534错误全面解析与实战解决方案
  • 如何让老旧Mac突破系统限制:OCLP-Mod的创新适配方案
  • Windows 11终极优化指南:使用Win11Debloat实现系统性能翻倍
  • AssetBundle打包粒度指南:如何平衡内存占用与加载效率?
  • 如何彻底解决手柄漂移问题:DS4Windows摇杆死区深度调校终极指南
  • LabVIEW调用HTTPS接口的保姆级教程:从抓取CA证书到GET天气数据