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

20-C语言:第21~22天笔记

C语言:第21~22天笔记

内容提要

数据块读写(二进制文件访问)
fread()

函数原型:

 #include <stdio.h>size_t fread(void *ptr, size_t size, size_t count, FILE *fp);

功能描述:

从文件流中读取数据块到内存缓冲区。主要用于二进制文件的读取操作。

参数说明:

参数类型说明
ptrvoid*指向存储读取数据的内存缓冲区指针
sizesize_t每个数据项的字节大小(例如:sizeof(int))
countsize_t要读取的数据项个数
fpFILE*指向要读取的文件流指针

返回值:

  • 成功返回实际读取的数据项个数(不是字节数)
  • 如果返回值小于count,可能表示:
    • 到达文件末尾(可用feof()检查)
    • 发生读取错误(可用ferror()检查)
fwrite()

函数原型:

 size_t fwrite(const void *ptr, size_t size, size_t count, FILE *fp);

功能描述:

将内存中的数据块写入到文件流中。主要用于二进制文件的写入操作,是fread()的配套函数。

参数说明:

参数类型说明
ptrconst void*指向要写入数据的内存缓冲区指针
sizesize_t每个数据项的字节大小(例如:sizeof(int))
countsize_t要写入的数据项个数
fpFILE*指向要写入的文件流指针

返回值:

  • 成功返回实际写入的数据项个数(不是字节数)
  • 如果返回值小于count,表示写入过程发生错误
案例:结构体读写

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 创建学生结构体
typedef struct Student
{int id;           // 学号char name[20];    // 姓名float scores[3];  // 三门成绩
} Stu;/*** @brief 从文件读取二进制数据* * @return */
void read_data(int len)
{// 打开文件FILE *fp = fopen("stu_data.dat", "rb");if (!fp){perror("文件打开失败!");return;}Stu n_stus[len];// 从二进制文件中读取数据size_t read_count = fread(n_stus, sizeof(Stu), len, fp);// 读取失败校验if (read_count < len){if (feof(fp)) printf("只读取到%lu条记录!\n", read_count);else /* else if(ferror(fp)) */{perror("读取文件时发生错误!");// 关闭文件fclose(fp);return;}	}// 关闭文件fclose(fp);for (size_t i = 0; i < len; i++){printf("学生%d:%s,语文-%.2f,数学-%.2f,英语-%.2f\n", n_stus[i].id, n_stus[i].name,n_stus[i].scores[0],n_stus[i].scores[1],n_stus[i].scores[2]);}}/*** @brief 向文件写入二进制数据* * @param stus * @param len * * @return */
int write_data(Stu *stus, int len)
{// 打开文件(文件不存在就创建)FILE *fp = fopen("stu_data.dat","wb");if (!fp){perror("文件打开失败!");return EXIT_FAILURE;}// 将stus以二进制形式写入到stu_data.dat文件size_t written = fwrite(stus, sizeof(Stu), len, fp);// 写入结果校验if(written < len){if (feof(fp)) printf("只写入了%lu条记录!\n", written);else perror("文件写入失败!");// 关闭文件fclose(fp);return EXIT_FAILURE;}printf("成功写入%lu条记录!\n", written);// 关闭文件return EXIT_SUCCESS;	
}int main(int argc, char *argv[])
{// 准备一个学生数组Stu stus[] = {{1, "张三", {89,88,97}},{2, "李四", {87,86,67}},{3, "王五", {81,83,87}}};int len = sizeof(stus)/sizeof(stus[0]);// 本地持久化(写入)write_data(stus,len);// 本地持久化(读取)read_data(len);printf("\n");return 0;
}

文件的随机访问

核心函数
  1. rewind(fp) - 重置到文件开头
  2. fseek(fp, offset, whence)- 定位文件指针
    • whence取值:
      • SEEK_SET:文件开头
      • SEEK_CUR:当前位置
      • SEEK_END:文件末尾
  3. ftell(fp) - 获取当前位置
  4. feof(fp) - 检测文件结束
案例
随机访问案例

#include <stdio.h>int main(int argc, char *argv[])
{FILE *fp = fopen("demo01.c", "r+");if (!fp){perror("文件打开失败!");return -1;}// 移动到文件末尾获取大小fseek(fp,0,SEEK_END);long size = ftell(fp);// 获取文件大小printf("文件大小:%ld字节\n",size);// 移动中间内容fseek(fp,size/2,SEEK_SET);// 读取文件内容char buf[256];while(!feof(fp))// 如果文件未读完,就循环读取{fgets(buf, sizeof(buf), fp);// 打印读取的内容printf("中间内容:%s\n",buf);}fclose(fp);return 0;
}
结构体读写

#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 创建学生类型(结构体)
typedef struct Student
{int id;          // 学号char name[20];   // 姓名float scores[3]; // 三门成绩
} Stu;/*** 向文件写入二进制数据*/
int write_data(FILE **fp)
{// 将stus写入到stu_data.dat// 准备要写入的学生数据Stu stus[3] = {{1, "张三", {89, 88, 97}},{2, "李四", {87, 86, 67}},{3, "王五", {81, 83, 87}}};// 向文件写入二进制数据size_t written = fwrite(stus, sizeof(Stu), sizeof(stus) / sizeof(stus[0]), *fp);if (written < 3){perror("数据写入失败!");fclose(*fp);return EXIT_FAILURE;}printf("成功写入%lu条学生记录\n", written);return EXIT_SUCCESS;
}/*** 读取二进制文件数据*/
int read_data(FILE **fp)
{// 重置文件指针都开头位置// rewind(*fp);fseek(*fp, 0, SEEK_SET);Stu stus[3];// 从二进制文件中读取信息size_t read_count = fread(stus, sizeof(Stu), sizeof(stus) / sizeof(stus[0]), *fp);// 读取失败if (read_count < 3){if (feof(*fp)) // 查看是否读取到文件末尾{printf("只读取到%lu条记录!\n", read_count);}else{perror("读取文件时发生错误!");}}// 读取成功,遍历for (size_t i = 0; i < read_count; i++){printf("学生%d:%s,语文-%.2f,数学-%.2f,英语-%.2f\n", stus[i].id, stus[i].name, stus[i].scores[0], stus[i].scores[1], stus[i].scores[2]);}return EXIT_SUCCESS;
}int main(int argc, char const *argv[])
{// 打开文件(文件不存在就创建)FILE *fp = fopen("stu_data.dat", "rb+");// 对二进制文件读写if (!fp){perror("文件打开失败!");return EXIT_FAILURE;}// 本地化保存数据(持久化保存数据)write_data(&fp);// 本地化数据读取(持久化数据读取)read_data(&fp);// 本地化数据读取(持久化数据读取)read_data(&fp);// 关闭文件fclose(fp);return 0;
}
http://www.dtcms.com/a/317185.html

相关文章:

  • V2X通信标准与消息数据结构详解
  • 异构系统数据集成之数据源管理:打通企业数据孤岛的关键一步
  • docker环境搭建
  • Qt Frameless Widget跨平台无边框窗口
  • 基于最大似然估计的卡尔曼滤波与自适应模糊PID控制的单片机实现
  • 鼠标下滑时回跳问题
  • 从“更优”到“更智”:V5.7.3 的交互革新、模式扩展与体验跃迁
  • NodeJs学习日志(1):windows安装使用node.js 安装express,suquelize,sqlite,nodemon
  • ESP32:2.搭建UDP服务器
  • 参考线程池构建一个高性能、配置驱动的Docker容器池
  • Linux---第二天---基础指令
  • copy_file_range系统调用及示例
  • 使用Nginx部署前后端分离项目
  • Docker的安装,服务器与客户端之间的通信
  • Linux基础命令的生产常用命令及其示例简单解释
  • 电子电气架构 ---如何焕新升级为 48V 电气架构
  • 【32】C++实战篇—— m行n列的坐标点,求每行相邻点X差值dX,每列相邻点y差值dY,并以矩阵形式左端对齐
  • 玩转 InfluxDB 3:用 HTTP API 快速创建高效数据表
  • Python科学计算:从基础到工程仿真的完整指南
  • 【java】DDD架构同普通微服务项目的区别
  • 23.统计分析:从数据中挖掘洞察
  • 深入浅出 RabbitMQ - 主题模式(Topic)
  • JavaWeb(04)
  • 丝滑qt页面跳转
  • android10~16变更一览和开发者兼容应对
  • 学习 Android(十五)NDK进阶及性能优化
  • antd组件select下拉数据分页加载
  • 学习 Android (十六) 学习 OpenCV (一)
  • Cglib的Enhancer实现动态代理?
  • 新能源汽车热管理系统核心零部件及工作原理详解