c++存取dat数据

news2024/9/23 19:21:06

      众所周知,dat是一个类似加密的二进制格式文件,很多人喜欢将游戏数据保存在dat文件中,只有知道你的存放格式,才能够将数据破解出来,因而研究了dat文件的存取方式。其实就是c++文件的操作,只不过是在取的时候需要按照自己存放的格式获取出来。

本文将实现将结构体数据保存到dat文件,并且将dat文件读取回来。

1.struct结构体的格式数据
      首先定义一个结构体,用以存放存入dat文件的数据,同时,再取的时候按照结构体的格式进行获取操作:
 

#pragma once
#ifndef _STRUCT_H_
#define _STRUCT_H_
 
#include<vector>
#include <iostream>
#include <string>
using namespace std;;
#define MaxSize 10
//设置结构体的边界对齐为1个字节,对于结构体中的char数组,如果不满4的倍数字节,会默认补齐,声明之后数据在内存中是连续存储的。
#pragma pack(1) 
typedef struct _TEST_DAT
{
	int type;
	char name[MaxSize];
	int age;
}TESTDAT;
 
#pragma pack()
 
#endif 

这时的结构体内存结构是对齐的。

2.TxtToFile存取dat文件

         先说存,首先初始化一个结构体,其次将该结构体数据依次保存到指定名字的dat文件中,如下:

TxtToFile.h:

#pragma once
#ifndef _TXT_TO_FILE_H_
#define _TXT_TO_FILE_H_
#include<vector>
#include <iostream>
#include <fstream>
#include <string>
#include "Struct.h"
#include <stdio.h>
using namespace std;
class TxtToFile
{
public:
	TxtToFile();
	~TxtToFile();
	//外调函数,保存到dat文件
	bool  SaveToDat(string _datPath);
private:
	TESTDAT	m_dat;
	fstream	m_datstream;
	vector<TESTDAT>	m_getdat;
 
private:
	// 把基本的Number类型写入文件流中
	template<class T>
	bool Write(T value)
	{
		//re
		m_datstream.write(reinterpret_cast<char *>(&value), sizeof(T));
		return true;
	}
	//把字符串写入文件流
	void  WriteString(string _str, int	_count);
};
#endif

TxtToFile.cpp :

#include "stdafx.h"
#include "TxtToFile.h"
#include <sstream>
 
TxtToFile::TxtToFile()
{
	m_dat = TESTDAT{
		0,
		"dasdasd",
		1
	};
	
}
 
 
TxtToFile::~TxtToFile()
{
}
bool TxtToFile::SaveToDat(string _datPath)
{
	if (_datPath.size() == 0)
	{
		return false;
	}
	m_datstream.open(_datPath, fstream::out | fstream::binary);//以二进制的形式打开文件
	if (!m_datstream.is_open())
	{
		cout << "open" << _datPath << "Failed" << endl;
		m_datstream.close();
		return false;
	}
	Write(m_dat.type);//存入数据
	WriteString(m_dat.name, MaxSize);
	Write(m_dat.age);
	//Write(m_dat);
	cout << "Successed" << endl;
	m_datstream.close();
	return true;
}
void TxtToFile::WriteString(string _str, int _count)
{
	if (_str.length()>=_count)
	{
		cout << "write string error!" << endl;
		return;
	}
	m_datstream << _str;
	int len = _count - _str.length();
	while (len--)
	{
		m_datstream << '\0';
	}
}

        这个时候,已经把数据存入到dat文件中,接下来就是取数据了,如下:

首先在头文件中加两个函数:

	//从dat文件读取数据
	bool GetFromDat(string _datPath);
	__int64 getFileSize(const char *filename);

cpp:

bool TxtToFile::GetFromDat(string _datPath)
{
	if (_datPath.size()==0)
	{
		return false;
	}
	
	__int64 scount = 0;
	__int64 stuctsize = sizeof(TESTDAT);
	TESTDAT testdat;
	__int64 filesize = getFileSize(_datPath.c_str());
	if (filesize==0|| filesize<stuctsize ||(filesize%stuctsize)!=0)
	{
		return false;
	}
	scount = filesize / stuctsize;
 
	FILE *inStream = NULL;
	const char* name = _datPath.c_str();
	inStream = fopen(name, "rb");
	if (inStream == NULL) return false;
	for (int i = 0; i < scount; i++)
	{
		//size_t fread(void *ptr, size_t size, size_t n, FILE *stream);
		//参数ptr是保存读取的数据,void*的指针可用任何类型的指针来替换,如char*、int *等等来替换;
		//size是每块的字节数;n是读取的块数,如果成功,返回实际读取的块数(不是字节数),本函数一般用于二进制模式打开的文件中。
		fread(&testdat, stuctsize, 1, inStream);
		/*if (testdat.duration < 0)
		{
			fclose(inStream);
			return false;
		}*/
		m_getdat.push_back(testdat);
	}
 
	fclose(inStream);
 
	return true;
}
 
__int64 TxtToFile::getFileSize(const char *filename)
{
	__int64 size = 0;
	/*FILE *fp = fopen(filename, "rb");
	if (!fp)
	{
		return 0;
	}
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	fclose(fp);*/
	fstream instreams;
	instreams.open(filename, ios::_Nocreate);
	if (!instreams.is_open())
	{
		return 0;
	}
	instreams.seekg(0, ios::end);
	size = instreams.tellg();
	instreams.close();
	return size;
}

读的时候用的是C语言的,因为映射一下就是结构体了,而且存的时候没有存空格\n\t之类的分隔符,所以用getline不好取。

3.测试样例

main函数:

// DatTxt.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include "TxtToFile.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
	TxtToFile ttofile;
	ttofile.SaveToDat("Test.Dat");
	ttofile.GetFromDat("Test.Dat");
	return 0;
}

运行视图:

 

成功,并且能在目录下找到dat文件,如果要看取出来的数据,那么需要加断点查看咯

Over

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/931131.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

批量记录当天收支明细,自动备份财务管理无忧!

在现代繁忙的生活中&#xff0c;财务管理变得越来越重要。我们为你提供了一款电脑高效记账专家&#xff0c;让你能够快速批量记录当天的收支明细&#xff0c;并设置自动备份&#xff0c;让财务管理变得更轻松 首先&#xff0c;第一步进入晨曦记账本主页面&#xff0c;点击上方功…

AutoCAD软件安装包分享

目录 一、软件简介 二、下载地址 一、软件简介 AutoCAD是一款专业的计算机辅助设计软件&#xff0c;用于帮助工程师、设计师和建筑师创建和编辑二维和三维模型。它提供了丰富的工具和功能&#xff0c;可以用于绘制、修改和分析各种设计项目。 AutoCAD具有直观的用户界面&am…

c++ qt--事件(第六部分)

c qt–事件&#xff08;第六部分&#xff09; 一.编辑伙伴&#xff0c;编辑顺序&#xff08;按TAB进行切换&#xff09; 1.编辑伙伴 此功能在设计界面如下的位置 1.设置伙伴关系 鼠标左键长按一个Label组件然后把鼠标移到另一个组件上 2.伙伴关系的作用 伙伴关系的作用就是…

ant design自定义展开折叠查看子项和点击行查看详情

实现思路&#xff1a;通过配置rowSelection&#xff0c;列表项是否可选择来实现。 页面内容&#xff1a; <a-table :dataSource"integrationBonds" :columns"columns" :customRow"customintegrationBondsRow":pagination"{hideOnSingle…

IDEA 配置注释模板

目录 一、配置类模板注释 二、配置方法注释 一、配置类模板注释 打开IDEA&#xff0c;打开settings(快捷键&#xff1a;Ctrl Alt s)&#xff0c;选择Editor&#xff0c;找到File and Code Templates&#xff0c;设置需要配置注释的文件类型&#xff0c;如下图所示&#xf…

深入剖析Kubernetes之Pod的实现原理

文章目录 概述Pod 的实现原理容器设计模式容器与虚拟机 Pod 的本质&#xff1a;Pod&#xff0c;实际上是在扮演传统基础设施里“虚拟机”的角色&#xff1b;而容器&#xff0c;则是这个虚拟机里运行的用户程序。 概述 容器&#xff0c;就是未来云计算系统中的进程&#xff1b;…

CSDN编程题-每日一练(2023-08-26)

CSDN编程题-每日一练&#xff08;2023-08-26&#xff09; 一、题目名称&#xff1a;排查网络故障二、题目名称&#xff1a;贪食四人帮三、题目名称&#xff1a;阿波罗的魔力宝石 一、题目名称&#xff1a;排查网络故障 时间限制&#xff1a;1000ms内存限制&#xff1a;256M 题目…

一文彻底告别 C盘 红色风景线

前言 想必使用 Windows 的用户肯定遇到过 C盘 爆满的问题吧&#xff0c;感觉平时我们也没有怎么使用 C盘 &#xff0c;但是 C盘 却总是慢慢成长&#xff0c;最后留给我们的就是一道靓丽的红色风景线。不过不用担心&#xff0c;相信读完本文后&#xff0c;在座的各位都可以永久…

精选6个C++项目,推荐新人练手首选!

无论做什么项目&#xff0c;在写简历时&#xff0c;最好要整理出项目中的技术点&#xff0c;思考如何跟面试官介绍你的项目&#xff0c;要经得起面试官的提问。项目的话&#xff0c;可以考虑做下面的这几个&#xff1a; 如果你想给自己的简历增加C 项目经验,以下提供一些方向指…

【C++奇遇记】函数模板

&#x1f3ac; 博客主页&#xff1a;博主链接 &#x1f3a5; 本文由 M malloc 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;LeetCode刷题集 数据库专栏 初阶数据结构 &#x1f3c5; 欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如…

高效PDF校对:释放高质量内容的力量

在数字化世界中&#xff0c;内容是王者。随着企业和个人越来越依赖数字文档进行沟通、分享和创新&#xff0c;我们在PDF中传递的内容的质量变得至关重要。在这里&#xff0c;我们将探索高效的PDF校对如何帮助您释放高质量内容的真正潜力。 超越仅仅是“正确” 当我们谈论PDF校…

MBR400100CT-ASEMI肖特基模块400A 100V

编辑&#xff1a;ll MBR400100CT-ASEMI肖特基模块400A 100V 型号&#xff1a;MBR400100CT 品牌&#xff1a;ASEMI 封装&#xff1a;M2 恢复时间&#xff1a;&#xff1e;50ns 正向电流&#xff1a;400A 反向耐压&#xff1a;100V 芯片个数&#xff1a;2 引脚数量&…

Leetcode77. 组合

给定两个整数 n 和 k&#xff0c;返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 回溯剪枝 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 class Solution {public List<List<Integer>> combine(int n, i…

展锐A13 Camera Hal dispatch模块流程 --- 上

4月份就知道展锐A13的Camera Hal有大的变动&#xff0c;但是最近一直在做一个MTK的项目&#xff0c;没去看这个新增部分的流程。最近有时间&#xff0c;就把A13上Camera Hal新增的部分流程捋 了一下&#xff0c;过程是痛苦的&#xff0c;但是坚持一遍遍去读代码&#xff0c;在结…

移动,电信,联通流量卡该怎么选?

是电信便宜&#xff0c;移动稳定&#xff0c;还是联通性价比高&#xff1f; ​ 今天&#xff0c;小编从三大流量卡的优缺点方面来讲&#xff0c;教你如何选择流量卡了。 一、移动流量卡 优点&#xff1a;信号好&#xff0c;可以说走到什么地方都有信号。 缺点&#xff1a;资…

Leaflet开发入门

Leaflet开发入门 开发环境配置Leaflet开发库开发移动端Hybrid App或移动Web App 开发环境配置 电子地图已经渗透到O2O、生活服务、出行等领域&#xff0c;传统的GIS也孕育着互联网基因。在国内互联网电子地图领域&#xff0c;百度地图和高德地图较为出色&#xff0c;天地图作为…

js的使用之时间如何定义,窗口加载事件

1.时间如何定义 1.1 date的其他的属性 带出星期几的写法 var arr [星期日,星期一,星期二,星期三,星期四,星期五,星期六,星期天] var day date.getDay(); console.log(arr[day]); 1.2 日期的格式化 1.3 时分秒的写法 固定写法&#xff1a;如果想要写成00:00:00这种形式&am…

阿里云服务器搭建FRP实现内网穿透-P2P

前言 在了解frp - p2p之前&#xff0c;请先了解阿里云服务器搭建FRP实现内网穿透-转发: 文章地址 1、什么是frp - p2p frp&#xff08;Fast Reverse Proxy&#xff09;是一个开源的反向代理工具&#xff0c;它提供了多种功能&#xff0c;包括端口映射、流量转发和内网穿透等。…

cmake 交叉编译应用程序:手动设置链接脚本

前言 在使用 cmake 交叉编译应该应用程序时&#xff0c;好像没有手动设置【链接脚本】&#xff0c;也能正常构建生成 Makefile&#xff0c;并且可以正常 Make 生成需要的 应用程序。 但是有些应用程序&#xff0c;需要手动指定【链接脚本】&#xff0c;比如修改链接地址&#…

五、多表查询-5.自连接

一、语法 二、演示-自连接&#xff08;内连接&#xff09; 【例】查询员工 及其 所属领导的名字&#xff08;managerid&#xff0c;领导也是员工表emp1表中的数据&#xff09; &#xff01;&#xff01;必须起别名&#xff01;&#xff01; ——内连接只查询交集部分的数据 …