逆序存储文件(二)——使用c标准库函数fopen,fseek,fread,fwrite

深信服C/C++开发H卷考点解析:从指针内存到系统设计 C/C++作为底层系统开发的核心语言,其技术价值体现在对内存布局、指针操作、并发控制等底层原理的精准掌控,是网络安全、云计算等高性能基础设施的关键支撑。从基础的字符串处理、文件读写,到多线程同步、网络通信与系统设计,每一环节都考验开发者对资源分配与异常路径的工程认知。在深信服等安全与云计算厂商的校招笔试中,这些知识不仅以选择题形式考察概念理解,更通过编程题和代码分析题检验候选人的实战素养。掌握指针生命周期、内存泄漏排查、文件I/O边界处理以及高效并发模型,是应对这类综合性测评的核心路径。围绕深信服校招C/C 阅读详情

使用c标准库函数实现小文件逆序存储逻辑是:

1.用fopen函数成功打开源文件和目标文件,源文件用只读方式(r)打开,目标文件用追加写入(a)的方式打开;

2.循环使用fseek定位文件指针(fopen的返回值),从SEEK_END(文件末尾)位置开始,每次多向前偏移一个字节,知道fseek返回一个非0值结束;(fseek能改变文件指针)

3.每次定位成功后,读取一个字符(fread)到缓冲区,读取成功后将缓冲区数据写入(fwrite)目标文件指针。

这边要注意4个函数的返回值,这些返回值是程序每一步执行的判断标志

fopen返回一个文件指针,返回NULL表示文件打开失败;

fseek返回一个整数,成功定位返回0,否则返回非0值;

fread返回读取的字符数。

测试代码如下:

#include <iostream>
#include <ctime>
#include <fstream>
#include <tchar.h>
using namespace std;
void ReverseCopy(const char* pSrcFile, const char* pDestFile)
{
	if(!pSrcFile || !pDestFile) return;

	time_t tBegin = time(0);

	FILE* pSrc = fopen(pSrcFile, "r");
	if(!pSrc) return;

	FILE* pDest = fopen(pDestFile, "a");
	if(!pDest) 
	{
		fclose(pSrc);
		return;
	}
	
	TCHAR ch[1] = {0};
	int nElementSize = sizeof(TCHAR);
	long lSeek = -nElementSize;
	while(fseek(pSrc, lSeek, SEEK_END) == 0)
	{
		if(fread(ch, nElementSize, 1, pSrc) > 0)
		{
			fwrite(ch, nElementSize, 1, pDest);
		}

		lSeek -= nElementSize;
	}

	fclose(pDest);
	fclose(pSrc);

	time_t tEnd = time(0);
	cout<<"File op time = "<<tEnd - tBegin<<endl;
}

int main()
{
	ReverseCopy("in.txt", "c_out.txt");
	
	return 0;
}


经过测试,该方法的性能也存在问题,不适合大文件.

 

修改:

以上方法只支持windows中ANSI编码的纯中文文本文件,因为UNICODE编码的工程中TCHAR为双字节,每次读取两个字节作为一个字符,遇到英文字符就会出现乱码,现在根据中文字符与英文字符的编码特点做以下修改。ANSI编码的文件中,中文字符(2个字节)高字节最高位为1,英文字符(1个字节)最高位为0,所以每次读取两个字节,与0x00008000作与运算,结果为真时,则将两个字节作为一个中文字符写入目标文件,否则,只写入高字节。ReverseCopy函数修改如下:

void ReverseCopy(const char* pSrcFile, const char* pDestFile)
{
	if(!pSrcFile || !pDestFile) return;

	time_t tBegin = time(0);

	FILE* pSrc = fopen(pSrcFile, "r");
	if(!pSrc) return;

	FILE* pDest = fopen(pDestFile, "a");
	if(!pDest) 
	{
		fclose(pSrc);
		return;
	}
	
	const int nflagChinese = 0x00008000;

	const int nWordSize = sizeof(WORD);
	const int nCharSize = 1;

	WORD ch[1] = {0};
	long lSeek = -2;
	bool bLastIsEn = false;//记录上次写入的是中文字符函数英文字符,如果是英文,那文件可能只剩一个字节,没法再向前seek两个字节
	while(fseek(pSrc, lSeek, SEEK_END) == 0)
	{
		if(fread(ch, nWordSize, 1, pSrc) > 0)
		{
			WORD wCh = ch[0];
			if(wCh & nflagChinese)//检查是否为中文字符
			{
				fwrite(ch, nWordSize, 1, pDest);
				lSeek -= 2;
				bLastIsEn = false;
			}
			else
			{//高字节为英文,只写入高字节
				BYTE b = HIBYTE(wCh);
				fwrite(&b, 1, 1, pDest);
				lSeek -= 1;
				bLastIsEn = true;
			}
		}
	}

	if(bLastIsEn && fseek(pSrc, ++lSeek, SEEK_END) == 0) 
	{//读取最后一个英文字节
		char lastCh[1] = {0};
		if(fread(lastCh, 1, 1, pSrc) > 0)
			fwrite(lastCh, 1, 1, pDest);
	}

	fclose(pDest);
	fclose(pSrc);

	time_t tEnd = time(0);
	cout<<"File op time = "<<tEnd - tBegin<<endl;
}


 

C 语言复习笔记 本文是东北林业大学计算机技术复试C语言复习笔记,主要涵盖C语言基础知识和程序设计要点。内容分为三部分:C语言概述、数据基础和顺序结构程序设计。第一部分介绍C语言特点(高效、灵活、支持底层操作)和程序结构(预处理指令、函数、变量等)。第二部分讲解常量、变量、标识符规则及基本数据类型,并详细说明各类运算符(算术、关系、逻辑等)的使用方法。第三部分阐述顺序结构程序设计原理,重点说明printf()格式化输出函数的使用。全文通过代码示例辅助理解,适合快速回顾C语言核心概念,但需注意部分内容可能不完全适用于其他用途。 阅读详情

相关推荐

linux C语言 文件逆序

C语言实现linux下文件逆序,使用系统调用。

IO学习三(fseek、ftell、rewind、fflush、 getline、临时文件)

我们现在要做这样一件事: fp=fopen(); 打开一个文件 fputc(fp) 10; 每次写进一个字符,写10次,就往文件中写了10个字符 fgetc() 10; 想要读出写进去的字符,那么就读10次 上面的逻辑是错误的,因为文件当中有一个文件位置指针,写的时候是依次向后移动,读的时候也是,像是一个游标。 读和写一定是从当前位置开始的,上面伪码在写完以后,位置指针最终指向的是第十个位置,然后读的时候,就会从第十一个位置开始。读的内容不知道。 有一个很笨拙地方法: fp=fopen(); fputc(f

m0_52547536的博客 568

超频玩家必看:TestMem5配置文件详解与内存稳定性测试实战(含黄金参数包)

本文详细解析了TestMem5(TM5)在内存超频稳定性测试中的核心价值与实战应用,特别针对DRAM颗粒特性提供黄金参数配置。通过anta777等专业配置的深度剖析,指导超频玩家精准定位内存故障,优化时序参数,实现性能与稳定性的完美平衡。涵盖从初级验证到极限压测的全流程方案,是硬件发烧友提升系统稳定性的必备指南。

weixin_29198045的博客 1812

fopen相关文件操作函数

1.fopen函数原型:FILE * fopen(const char * path,const char * mode);

Lyu-ming 栏目 1233

UE5深度图与Mask图渲染实战:从基础到高级应用

本文详细解析了在UE5中渲染深度图与Mask图的完整实战流程。从启用电影渲染队列、配置自定义深度模板通道等前期准备,到构建即用型深度图材质网络与精准物体Mask生成,并深入探讨了二者结合在NPR风格化、程序化雾气及AI工作流(如ComfyUI)中的高级应用,为影视、游戏后期与AI创作提供了高效的解决方案。

weixin_29001419的博客 349

Kaggle时间序列竞赛金牌方案解析与实战指南

本文深度解析了Kaggle时间序列竞赛的金牌方案,揭示了其成功不仅依赖先进模型,更在于系统工程思维。文章系统阐述了从数据理解、特征工程到模型集成与后处理的全流程,并重点剖析了分层建模、自定义损失函数、时序交叉验证等核心技巧,为参赛者提供了从理论到实战的完整指南。

weixin_29196315的博客 356

随机访问:fseek()和ftell()函数(C语言学习笔记)

随机访问:fseek()和ftell()函数 C语言学习笔记

weixin_46429500的博客 1224

从零搭建openEuler ARM64开发测试环境:手把手教你用libvirt+KVM配置虚拟机(含VNC远程安装)

本文详细介绍了如何在ARM64平台上从零搭建openEuler开发测试环境,涵盖libvirt和KVM配置虚拟机的完整流程,包括环境准备、存储配置、网络优化、XML配置详解以及VNC远程安装。特别针对华为欧拉(openEuler)系统进行了优化,帮助开发者快速构建高效的ARM架构虚拟化环境。

weixin_30545945的博客 586

c语言写txt文件fwrite,文件操作 fwrite,该怎么处理

文件操作 fwrite#include//?ftellrewind#include//exit//fwrite(&stu[0],sizeof(structstudent),2,fp)写入//2个结构体structstudent{intage;charname[40];}stu[3]={{23,"fvsef"},{45,"如果好的"},{56,"sc的v"}},s;intma...

weixin_35529208的博客 1462

在轻量化与精度之间取得平衡:YOLOv8 + GhostNet 的设计与实验分析

摘要: GhostNet系列(GhostNet、GhostNetv2、GhostNeXt)通过“幽灵特征图”技术,以极低计算量生成丰富特征,为YOLOv8提供轻量化改造方案。该技术能在减少参数量与计算量的同时保持或提升检测精度,适用于边缘设备部署。实现时需替换YOLOv8的Backbone为GhostNet模块,并通过消融实验验证其有效性。实验数据表明,改造后的模型在参数量降低30%的同时,推理速度提升28.6%,mAP@0.5最高提升1.9个百分点,平衡了轻量化与精度,为毕设提供技术创新性与工程落地性的双

m0_64661770的博客 194

红米k60 修复“NV损坏” 去除主板校验电阻步骤解析与图示

红米k60 基带代码:mondrian。搭载‌高通骁龙8+ Gen1处理器.国外版本称:POCO F5 Pro适用于以下型号的小米机型:23013RK75C, 23013PC75G。 💝💝💝通过博文了解 1💝💝💝-----此机型修复NV损坏硬件类操作主板图示 2💝💝💝-----了解设备出现NV损坏的底层逻辑 3💝💝💝 ------具体修改步骤

小马哥的专栏 393

写文件fwrite函数的用法

到目前位置,我们已经学习了C语言读写文件的函数fprintf和fscanf函数,除了这对格式化文件读写函数之外,还有很多。今天介绍的fwrite函数就是写文件的函数,它的函数原型如下: 1 size_tfwrite(constvoid*ptr,size_tsize,size_tnmemb,FILE*stream) 可以看到这个函数的参数有四个: 第一个ptr是要写入的数据的头指针,无符号类型; 第二个参数size是大小,表示每个写入元素的大小...

m0_60226024的博客 2566

21、二维卷积层(convolution2dLayer)的全面解析

本文全面解析了二维卷积层(convolution2dLayer)的原理、属性和应用,详细介绍了其在深度学习中的作用及实现方法。文章涵盖创建卷积层的语法、参数设置、算法原理、输入输出格式、优化策略以及实际应用案例,旨在帮助读者更好地理解和应用二维卷积层构建高效的深度学习模型。

red88的博客 316

C/C++文件操作干货

注意:如果不使用绝对路径(完整的建立路径,如:c:\yyy\xxx\xx.txt)而是直接用文件名(xx.txt),每次建立新文件夹的时候都会在默认路径,如果想要在默认路径前一个目录(如:xxx)中建立,只需要把("test.txt","w+")改为("./../test.txt","w+"),前两个就是("./../../test.txt","w+").从键盘,网络,c盘等储存设备中读取数据的读取方式方式各不相同,同样的,输出数据的方式也有许多(比如输出到屏幕,写在文件中);

2302_80221042的博客 1795

《AgentScope-Java 深入浅出教程》第1章 AgentScope-Java 简介

AgentScope-Java 是一个面向智能体的编程框架,专门用于构建基于大语言模型(LLM)的 AI 应用程序。│ 你的业务应用 ││ AgentScope-Java 框架 ││ │ 智能体 │ │ 工具 │ │ 记忆 │ │ 模型 │ ││ LLM 服务 (DashScope/OpenAI/...) │能力说明类比ReAct 推理让智能体能够"思考"并"行动"就像人类思考后再做事工具调用让智能体能够执行外部操作就像人使用计算器、搜索引擎记忆管理让智能体能够记住对话历史。

步子哥的博客 592

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

C语言期末考试应急指南

本文摘要: C语言基础速查手册,涵盖程序结构、数据类型、运算符等核心内容。主要包括:1) 最小程序结构(main函数框架)和编译流程(预处理、编译、汇编、链接);2) 基本数据类型(整型、浮点型等)及其修饰符,变量声明与初始化方法;3) 常量的多种表示方式(整型、浮点、字符、字符串)及转义字符;4) 运算符分类(算术、关系、逻辑等)和使用要点。手册采用表格形式呈现关键知识点,如数据类型大小、格式化符号、运算符优先级等,便于快速查阅。特别强调C语言特性:面向过程、弱类型检查、手动内存管理等,适合初学者快速掌握

qq_38856191的博客 1983

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

C 语言标准 IO 与系统调用 IO

关于C标准IO与系统调用IO的概念与对比。摘要需涵盖核心要点。不超过150字。</think>标准 IO 与系统调用 IO 是 C 语言两种 IO 方式:前者基于 FILE* 带缓冲,可移植且高效;后者基于文件描述符。优先用标准 IO。标准 IO 提供 fopen/fclose、字符、行、块读写等接口,注意 fopen 模式、缓冲区及错误处理。

Lixxinx的博客 302

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

C/C++ | 18-3 递归反向输出字符串

递规反向输出字符串的例子,可谓是反序的经典例程 /* 递规反向输出字符串 */ #include #include #include #include #include using namespace std; void inverse(char *p) { if (*p == '\0') return; else { inverse(p + 1); p

qq_38362761的博客 1559

C语言文件操作(2)

关于c语言的文件操作的介绍(2)!!

Gujiu的博客 1600

fread,fwrite,fopen,fclose

fread,fwrite,fopen,fclose 1.用法: int fread(void *buffer,int size,int count,FILE *fp); int fwrite(void *buffer,int size,int count,FILE *fp); 2.功能: fread()──从fp所指向文件的当前位置开始,一次读入size个字节,重复count次,并将读入的数据存放到从buffer开始的内存中; buffer是存放读入数据的起始地址(即存放何处)。 fwrite()──从bu

aipisces的专栏 3399

使用fseek()函数从文件尾部前移并且写入数据

首先,打开文件

那年晴天的博客 3696

C语言实现字符串拷贝并逆序的问题

题目要求实现函数 void reverse_copy(char* dst, const char* src); 要求:不能在函数中定义任何变量 void reverse_copy(char* dst, const char* src) { (*dst)++; if(*src == '\0') { *(dst + (*dst) - 1) = *dst; *dst = 0; retur

priest334的专栏 1360

倒序取字符串函数

PARAMETERS c CLEAR P=SPACE(0) I=1 DO WHILE I<=LEN(C) x=ASC(SUBSTR(C,I,1)) IF x>127 P=SUBSTR(C,I,2)+P I=I+1 ELSE P=SUBSTR(C,I,1)+P ENDIF I=I+1 ENDDO *

lygcw9602的专栏 2074

两种获取虚函数地址的方式

今天在运行一段代码时,发现运行结果与我预期的不一样,所以google了一把,这里对研究结果作下总结 #pragma once #include using std::cout; using std::endl; class Base { public: virtual void f() { cout<<"Base f"<<endl; } virtual v

sunchenx的专栏 3321
上一篇: 逆序存储小文件(一)——使用STL容器
下一篇: 逆序存储文件(三)——文件内存映射
sunchenxian017
博客等级 码龄16年 2粉丝 13原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值