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

文件操作:fgets与gets区别+fread/fwrite +流定位接口

一、fgets和gets的区别

1.fgets

  • 从指定的已打开文件中读取最多一行数据,遇到\n停止读取。
  • fgets会读取一个换行,并在末尾自动加一个'\0'。
  • fgets最多读取size - 1个字符,最后一个位置存放\0。
  • 取掉fgets的\n换行。eg:s[strlen(s) - 1] = '\0';

2.gets

  • 从指定终端设备读取数据。
  • gets会将终端读到的\n字符替换成\0。
  • gets是危险的,因为在读取时,没有大小的限制,可能会造成内存越界。

二、二进制流的输入输出

1.size_t fwrite(const void *ptr,size_t size,size_t nmemb,FILE *stream)

(1)结构说明

  • 功能:向文件写入nmemb个大小为size的数据到文件中。
  • 参数:ptr-要写入的数据的首地址

                  size-每个元素的字节数

                  nmemb-要写入的元素个数

                  stream-要写入的文件流指针

  • 返回值:成功:返回实际写入元素个数

   (2)示例程序

#include<stdio.h>struct stu
{int id;char name[32];int score;
};    //定义结构体int main(int argc,const char argv[])
{FILE *fp = fopen("1.txt","w");        //打开文件if(NULL == fp){printf("fopen erro");return -1;}                                    //判断是否成功打开文件struct stu s[5] = {{1,"zhangsan",99},{2,"lisi",88},{3,"wanger",66},{4,"maliu",77},{5,"zhaowu",100}};size_t cnt = fwrite(&s,sizeof(struct stu),3,fp);printf("cnt = %ld\n",cnt);fclose(fp);return 0;
}

2.size_t fread(void *ptr,size_t size,size_t nmemb,FILE *stream)

(1)结构说明

  • 功能:向文件中读取nmemb个大小为size的元素。
  • 参数:ptr-存储读取到数据的首地址

                  size-每个元素的字节数

                  nmemb-希望从文件中读取的元素个数

                  stream-要读取的文件的文件流指针

  • 返回值:成功:返回实际读取的元素个数

                      读到文件末尾:0

(2)示例程序

#include<stdio.h>
struct stu
{int id;char name[32];int score;
};int main(int argc, const char argv[])
{FILE *fp = fopen("1.txt","r");if(NULL == fp){printf("fopen erro");return -1;}struct  stu s[10];size_t cnt = fread(s,sizeof(struct stu),5,fp);for(int i = 0;i < cnt; ++i){printf("%d %s %d\n",s[i].id,s[i].name,s[i].score);}fclose(fp);return 0;
}

三、流定位相关接口

1.fseek-----int fseek(FILE *stream,long offset,int whence)

  • 功能:实现文件流重新定位
  • 参数:stream--需要定位的文件流指针

                  offset--偏移量

                  whence--定位的相对位置➡SEEK_SET:从头进行偏移

                                                           ➡SEEK_CUR:从当前位置进行偏移

                                                            ➡SEEK_END:从末尾进行偏移

  • 返回值:成功:返回当前的偏移量

                      失败:-1

  • 示例程序:
#include <stdio.h>int main(int argc, const char *argv[])
{FILE *fp = fopen("./1.txt", "w");if (NULL == fp){printf("fopen error\n");return -1;}fseek(fp, 10, SEEK_SET);fputc('A', fp);long offset = ftell(fp);printf("offset = %ld\n", offset);fseek(fp, 5, SEEK_CUR);fputc('B', fp);offset = ftell(fp);printf("offset = %ld\n", offset);fseek(fp, -2, SEEK_CUR);fputc('C', fp);fseek(fp, 4, SEEK_END);fputc('D', fp);fseek(fp, -10, SEEK_END);fputc('E', fp);fclose(fp);return 0;
}

            通过运行程序可知,其偏移量可正可负。

2.ftell -- long ftell(FILE *stream)

  • 功能:获取流的当前位置到文件开头的偏移量
  • 参数:stream--需要定位的文件流指针
  • 返回值:偏移量:byte

3.rewind--void rewind(FILE *stream)

  • 功能:流复位函数(复位到开头)

4.应用

  • 获取文件的大小(字节数)

    fseek(fpsrc, 0, SEEK_END);
long len = ftell(fpsrc);
rewind(fpsrc);        //文件流指针复位

#include<stdio.h>
int main(int argc,const char *argv[])
{FILE *fp = fopen("fread.c","r");if(NULL == fp){printf("fopen error\n");return -1;}fseek(fp,0,SEEK_END);long offset = ftell(fp);offset = ftell(fp);printf("offset = %ld\n",offset);fclose(fp);return 0;
}
  • 产生一个空洞文件➡抢占磁盘空间(结束后必须复位)

    fseek(fpdst, len-1, SEEK_SET);
int ret = fputc('\0', fpdst);
if (EOF == ret)
{
printf("磁盘空间不足\n");
return -1;
}

rewind(fp);        //复位

4.综合程序示例

程序实现的功能:

示例程序:

#include <stdio.h>
#include <stdlib.h>int main(int argc, const char *argv[])
{if (argc < 3){printf("Usage : ./a.out <srcfile> <dstfile>\n");return -1;}FILE *fpsrc = fopen(argv[1], "r");if (NULL == fpsrc){printf("fopen error srcfile\n");return -1;}//1、 获取源文件大小fseek(fpsrc, 0, SEEK_END);long len = ftell(fpsrc);rewind(fpsrc);//2、抢占目标文件的磁盘空间FILE *fpdst = fopen(argv[2], "w");if (NULL == fpdst){printf("fopen error dstfile\n");return -1;}fseek(fpdst, len-1, SEEK_SET);int ret = fputc('\0', fpdst);if (EOF == ret){printf("磁盘空间不足\n");fclose(fpsrc);fclose(fpdst);return -1;}rewind(fpdst);	//3、数据拷贝char buff[1024] = {0};while (1){size_t cnt = fread(buff, 1, sizeof(buff), fpsrc);if (0 == cnt){break;}fwrite(buff, 1, cnt, fpdst);}fclose(fpsrc);fclose(fpdst);return 0;
}

http://www.lryc.cn/news/617463.html

相关文章:

  • 【图像处理基石】PCA图像压缩与还原:基于OpenCV的Lena图实验
  • 2025 算法面试试题-阿里面试题分析
  • 【算法专题训练】11、字符串中的变位词
  • PyTorch基础(使用Tensor及Antograd实现机器学习)
  • GraalVM !拥抱云原生的 JVM
  • foreach 块并行加速
  • docker compose和docker-compose命令的区别
  • 力扣164:最大间距
  • 大数据系统架构模式:驾驭海量数据的工程范式
  • React(四):事件总线、setState的细节、PureComponent、ref
  • LeetCode 2438.二的幂数组中查询范围内的乘积:模拟(前缀和可选)
  • C++项目实战(日期类的实现)
  • MFC C++ 使用ODBC方式调用Oracle数据库的详细步骤
  • 重学React(五):脱围机制一
  • 金蝶云星辰:赋能企业数据管理
  • spring boot 整合redis教程
  • 带简易后台管理的米表系统 域名出售系统 自适应页面
  • 帝国理工学院团队研发:Missense3D-PTMdb—— 解析遗传变异与翻译后修饰的交互式工具
  • 计算机网络---交换机
  • 套接字技术、视频加载技术、断点续传技术
  • Horse3D引擎研发笔记(四):在QtOpenGL下仿three.js,封装EBO绘制四边形
  • 2025 年国内可用 Docker 镜像加速器地址
  • Rust面试题及详细答案120道(19-26)-- 所有权与借用
  • 《基于Pytorch实现的声音分类 :网页解读》
  • YOLOv8 训练报错:PyTorch 2.6+ 模型加载兼容性问题解决
  • 【JavaEE】(12) 创建一个 Sring Boot 项目
  • 第二届机电一体化、机器人与控制系统国际会议(MRCS 2025)
  • 34-Hive SQL DML语法之查询数据-3
  • 2025世界机器人大会,多形态机器人开启商业化落地浪潮
  • [4.2-2] NCCL新版本的register如何实现的?