news 2026/6/23 10:58:05

应用——文件I/O操作代码

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
应用——文件I/O操作代码

文件I/O操作代码分析

一、基础文件操作

1. 打开文件 -01open.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { int fd = open("1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); if (-1 == fd) { fprintf(stderr, "open error\n"); return 1; } return 0; }

知识点

  • open():系统调用打开文件

  • flags参数

    • O_WRONLY:只写模式

    • O_CREAT:文件不存在时创建

    • O_TRUNC:清空文件内容

  • mode参数0666表示文件权限(用户、组、其他都可读写)

  • 文件描述符:成功返回非负整数,失败返回-1

2. 写入文件 -04write.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { int fd = open("1.txt", O_WRONLY | O_CREAT | O_TRUNC, 0666); char str[100] = "hello"; ssize_t ret = write(fd, str, strlen(str)); printf("写入了%ld字节到文件", ret); close(fd); return 0; }

知识点

  • write(fd, buf, count):写入数据

  • strlen(str)vssizeof(str)

    • strlen(str):实际字符串长度(不包括'\0')

    • sizeof(str):数组总大小(100字节)

  • ssize_t:有符号整数类型,表示实际写入字节数

  • 必须调用close(fd)释放资源

3. 读取文件 -05read.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { int fd = open("/etc/passwd", O_RDONLY); char buf[50] = {0}; while (1) { bzero(buf, sizeof(buf)); // 清空缓冲区 int ret = read(fd, buf, sizeof(buf)-1); // 留一个位置给'\0' if (ret <= 0) break; printf("[%d]:{%s}", ret, buf); } close(fd); return 0; }

知识点

  • read(fd, buf, count):读取数据

  • 缓冲区清空

    • bzero(buf, sizeof(buf)):将内存清零

    • memset(buf, 0, sizeof(buf)):功能相同

  • 读取策略sizeof(buf)-1保留一个字节给字符串结束符

  • 返回值

    • >0:实际读取字节数

    • =0:文件结束

    • <0:错误

4. 文件复制 -06read_cp.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { if (argc < 3) { printf("usage: ./a.out srcfile dstfile\n"); } int fd_src = open(argv[1], O_RDONLY); int fd_dst = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0666); while (1) { char buffer[1024] = {0}; int ret = read(fd_src, buffer, sizeof(buffer)); if (ret <= 0) break; write(fd_dst, buffer, ret); } close(fd_dst); close(fd_src); return 0; }

知识点

  • 命令行参数argv[1]源文件,argv[2]目标文件

  • 分块读取:循环读取直到文件结束

  • 精确写入write(fd_dst, buffer, ret)只写入实际读取的字节

  • 资源管理:最后关闭两个文件描述符

二、高级文件操作

1. 文件插入 -02insert_file.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { FILE* fp = fopen("1.txt", "r+"); // 获取文件大小 fseek(fp, 0, SEEK_END); long size = ftell(fp); int pos = 15; char insert_str[100] = "hello"; // 保存后半部分内容 fseek(fp, pos, SEEK_SET); char *data = (char*)malloc(size); fread(data, size-pos, 1, fp); // 插入内容 fseek(fp, pos, SEEK_SET); fwrite(insert_str, strlen(insert_str), 1, fp); fwrite(data, size-pos, 1, fp); fclose(fp); free(data); return 0; }

知识点

  • 标准I/O:使用fopen()fread()fwrite()

  • 文件定位

    • fseek(fp, 0, SEEK_END):移动到文件末尾

    • ftell(fp):获取当前位置(即文件大小)

  • 插入策略

    1. 读取插入点之后的内容到内存

    2. 在插入点写入新内容

    3. 追加原来的后半部分内容

  • 内存管理:使用malloc()动态分配,最后free()

2. 文件定位 -08lseek.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { int fd = open("1.txt", O_RDWR); // 获取文件大小 long size = lseek(fd, 0, SEEK_END); printf("size %ld\n", size); // 移动到指定位置并写入 lseek(fd, 1024*1024, SEEK_SET); char str[] = "老孙到此一游"; write(fd, str, strlen(str)); close(fd); return 0; }

知识点

  • lseek(fd, offset, whence):移动文件指针

    • SEEK_SET:从文件开头

    • SEEK_CUR:从当前位置

    • SEEK_END:从文件末尾

  • 空洞文件:跳过大量字节后写入,中间部分会被填'\0'

  • 文件大小:使用lseek(fd, 0, SEEK_END)获取文件大小

三、标准输入输出

07stdin.c

#include <fcntl.h> #include <stdio.h> int main(int argc, char **argv) { char buf[10] = {0}; printf("pls input num:"); fflush(stdout); // 强制刷新缓冲区 read(0, buf, sizeof(buf)); // 从标准输入读取 int num = atoi(buf); write(2, &num, 4); // 写入标准错误 return 0; }

知识点

  • 标准文件描述符

    • 0:标准输入(stdin)

    • 1:标准输出(stdout)

    • 2:标准错误(stderr)

  • 缓冲机制

    • printf()输出到缓冲区,需要刷新才能显示

    • fflush(stdout)强制刷新输出缓冲区

  • 字符串转换atoi()将字符串转换为整数

  • 系统调用读写read()/write()也可以操作标准输入输出

四、应用实例

字典程序 -03dict.c

#include <stdio.h> #include <stdlib.h> #include <string.h> #include "list.h" typedef struct { char word[50]; char mean[512]; struct list_head node; } DATATYPE; int main(int argc, char** argv) { // 1. 打开字典文件 FILE* fp = fopen("/home/linux/dict.txt", "r"); // 2. 初始化链表 struct list_head dict_head; INIT_LIST_HEAD(&dict_head); // 3. 读取并存储字典数据 while (1) { char str[1024] = {0}; if (NULL == fgets(str, sizeof(str), fp)) break; char* word = strtok(str, " "); char* mean = strtok(NULL, "\r"); add_word(&dict_head, word, mean); } // 4. 用户查询交互 while (1) { char want_word[50] = {0}; printf("pls input want_word:"); fgets(want_word, sizeof(want_word), stdin); want_word[strlen(want_word) - 1] = '\0'; // 去掉换行符 if (0 == strcmp(want_word, "#quit")) break; DATATYPE* tmp = find_word(&dict_head, want_word); if (NULL == tmp) { printf("cant find word:%s\n", want_word); } else { printf("word:%s mean:%s\n", tmp->word, tmp->mean); } } return 0; }

核心知识点

  1. 文件读取

    • fgets(str, sizeof(str), fp):安全读取一行

    • 检查NULL判断文件结束// 原始格式:单词 解释\r\n

  2. char* word = strtok(str, " "); // 第一个空格前是单词 char* mean = strtok(NULL, "\r"); // 到\r前是解释 fgets(want_word, sizeof(want_word), stdin);
  3. want_word[strlen(want_word) - 1] = '\0'; // 去掉末尾的换行符
  4. 链表操作

    • list_add(&p->node, head):添加到链表

    • list_for_each_entry_safe():安全遍历链表

五、重要总结

1. 系统调用 vs 标准I/O

操作系统调用标准I/O
打开open()fopen()
读取read()fread()
写入write()fwrite()
关闭close()fclose()
定位lseek()fseek()

2. 常用文件打开模式

模式说明
O_RDONLY只读
O_WRONLY只写
O_RDWR读写
O_CREAT不存在时创建
O_TRUNC清空文件
O_APPEND追加模式

3. 错误处理模式

int fd = open("file.txt", O_RDONLY); if (-1 == fd) { perror("open failed"); // 自动添加错误信息 // 或 fprintf(stderr, "open error: %s\n", strerror(errno)); return 1; }

4. 内存与文件操作注意事项

  1. 缓冲区管理:读取前清空,写入时注意长度

  2. 资源释放:打开后必须关闭,分配后必须释放

  3. 错误检查:每个系统调用都可能失败

  4. 边界检查:防止缓冲区溢出

  5. 文件权限:创建文件时指定合适的权限

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/23 23:18:41

SpringBoot3+Vue3新闻动态网站

基于 Spring Boot 3.1.5 MyBatis-Plus 3.5.8 Vue3 MySQL Element-Plus 开发的校园新闻动态网站系统。技术栈后端Spring Boot 3.1.5MyBatis-Plus 3.5.8MySQLJWT 认证Hutool 工具类前端Vue 3Vue Router 4PiniaElement PlusEChartsWangEditor 富文本编辑器Axios功能模块用户角…

作者头像 李华
网站建设 2026/6/23 23:18:57

销售年终汇报再也不难写:AI自动把你的业绩转成完整PPT

引言 每到年终&#xff0c;销售们撰写年终汇报就成了一大难题。不仅要详细梳理全年业绩&#xff0c;还要将这些内容精心整理成一份逻辑清晰、美观专业的 PPT。手动撰写和制作 PPT 不仅耗时费力&#xff0c;还容易出现内容结构混乱、排版不美观等问题&#xff0c;让本就忙碌的销…

作者头像 李华
网站建设 2026/6/22 16:15:05

高性能ESAM芯片LKT4305GM

ESAM芯片是一种嵌入式安全控制模块&#xff0c;主要用于数据加密存储、身份认证和终端安全防护。其核心功能包括支持多种加密算法、通信协议和双向认证机制&#xff0c;广泛应用于智能表计、金融设备等领域。随着云计算、大数据等技术的广泛应用&#xff0c;数据中心对高速、多…

作者头像 李华
网站建设 2026/6/23 19:08:50

销售年终总结PPT这样做最快:AI一键生成,从业绩到亮点全自动呈现

引言 每到年末&#xff0c;销售们都要撰写年终总结PPT。然而&#xff0c;整理业绩数据、突出工作亮点、规划未来方向&#xff0c;这些内容繁琐且耗费时间。手动制作PPT不仅要花费大量时间排版&#xff0c;还可能因为缺乏设计经验&#xff0c;导致PPT结构混乱、美观度不足。如何…

作者头像 李华
网站建设 2026/6/23 0:17:28

销售工作太杂做不出PPT?AI自动帮你生成逻辑清晰的年终总结

引言 销售工作涉及客户跟进、业绩统计、市场分析等众多繁杂事务。到了年终&#xff0c;要把这些琐碎的工作整理成一份逻辑清晰的年终总结PPT&#xff0c;让不少销售人头疼不已。自己手动整理内容&#xff0c;不仅费时费力&#xff0c;还容易出现结构混乱的问题&#xff0c;难以…

作者头像 李华
网站建设 2026/6/22 14:21:34

指针,不多的记录

#include<stdio.h>int main(){int temp[5] {1,2,3,4,5};int *p temp;)——>,数组是连续的&#xff0c;所以只需要直到第一个地址int i;for(i 0;i<5;i){printf("%d\n",*(pi));}return 0;}是一个数组&#xff0c;每个数组元素存放一个指针变量int *p1[5…

作者头像 李华