c++存取dat数据

      众所周知,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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

git管理代码

理论上改代码前要pull一次&#xff0c;然后在push前在pull一次 改代码前pull一次是为了获取最新的同步&#xff0c;但是coding也是需要时间的&#xff0c;难保敲代码的这段时间没有人动远程仓库的东西&#xff0c;所以在改完代码要push的时候也应该再pull一下看有无冲突&#x…

jvs-rules(规则引擎)更新:新增功能介绍

jvs-rules更新内容 1.复合变量新增数据补充节点&#xff0c;实现请求回来的数据再以入参方式请求其他数据进行数据补充&#xff08;例如通过参数A&#xff0c;请求回数据B&#xff0c;再以数据B为入参&#xff0c;请求回数据C&#xff09; 2.规则流结束节点支持新增、新建、引…

c++都补了c语言哪些坑?

目录 1.命名空间 1.1 定义 1.2 使用 2.缺省参数 2.1 概念 2.2 分类 3.函数重载 4.引用 4.1 概念 4.2 特性 4.3 常引用 4.4 引用和指针的区别 5.内联函数 1.命名空间 在 C/C 中&#xff0c;变量、函数和后面要学到的类都是大量存在的&#xff0c;这些变量、函数和类的名称将…

使用go语言、Python脚本搭建一个简单的chatgpt服务网站。

使用go语言、Python脚本搭建一个简单的GPT服务网站 前言 研0在暑假想提升一下自己&#xff0c;自学了go语言编程和机器学习相关学习&#xff0c;但是一味学习理论&#xff0c;终究是枯燥的&#xff0c;于是自己弄点小项目做。 在这之前&#xff0c;建议您需要掌握以下两个技…

人力资源小程序的设计原则与实现方法

随着移动互联网的快速发展&#xff0c;小程序成为了各行各业推广和服务的新利器。对于人力资源行业来说&#xff0c;开发一款定制化的小程序不仅可以提升服务效率&#xff0c;还可以增强品牌形象和用户粘性。那么&#xff0c;如何定制开发人力资源类的小程序呢&#xff1f;下面…

深度丨Serverless + AIGC,一场围绕加速创新的升维布局

作者&#xff1a;褚杏娟 上图来源于基于函数计算部署 SD实现光影效果 前言&#xff1a; Serverless 在中国发展这些年&#xff0c;经历了高潮、低谷、现在重新回到大众视野。很多企业都非常感兴趣&#xff0c;部分企业开始大规模应用&#xff1b;也有一些企业对在生产环境真正…

【pytorch】Unfold和Fold的互逆操作

1. 参数定义 Unfold https://pytorch.org/docs/stable/generated/torch.nn.Unfold.html#torch.nn.Unfold Fold https://pytorch.org/docs/stable/generated/torch.nn.Fold.html#torch.nn.Fold 注意&#xff1a;参数当中的padding是在四周边补零&#xff0c;而当fold后的尺寸…

找风景类视频素材就上这5个网站

免费高清的风景视频素材&#xff0c;我推荐你去这几个网站下载&#xff0c;赶紧收藏起来~ 菜鸟图库 https://www.sucai999.com/video.html?vNTYxMjky 菜鸟图库网素材非常丰富&#xff0c;网站主要还是以设计类素材为主&#xff0c;高清视频素材也很多&#xff0c;像风景、植…

Docker创建Consul并添加权限控制

一、部署Consul 1、拉取镜像&#xff1a; docker pull consul:<consul-version> 2、运行 docker run --name consul1 -p 8300:8300/tcp -p 8301:8301/tcp -p 8301:8301/udp -p 8302:8302/tcp -p 8302:8302/udp -p 8500:8500 -p 8600:8600/tcp -p 8600:8600/udp -v /h…

建设全球研发中心城市,长沙政协将会发挥怎样的作用?

政协力量&#xff0c;会如何推动一座城市的发展&#xff1f;在全国各大城市都力“拼经济、搞创新”的时代大背景下&#xff0c;人民政协的力量会如何助推长沙建设全球研发中心城市呢&#xff1f; 这是笔者此前一直很好奇的两个问题。8月24日&#xff0c;一场由长沙市政协举办的…

《存储IO路径》专题:数据魔法师DMA

初识DMA 大家好,今天我要给大家介绍一位在计算机世界中不可或缺的魔法师——DMA(Direct Memory Access)。让我们一起揭开这位魔法师的神秘面纱,看看它是如何让数据在内存之间自由穿梭的。 DMA这位魔法师可是大有来头。在现代计算机系统中,CPU、内存和各种设备之间需要进…

Android 之 LayoutInflater (布局服务)

本节引言&#xff1a; 本节继续带来的是Android系统服务中的LayoutInflater(布局服务)&#xff0c;说到布局&#xff0c;大家第一时间 可能想起的是写完一个布局的xml&#xff0c;然后调用Activity的setContentView()加载布局&#xff0c;然后把他显示 到屏幕上是吧~其实这个底…

2.含电热联合系统的微电网运行优化

含电热联合系统的微电网运行优化 MATLAB代码&#xff1a;含电热联合系统的微电网运行优化 关键词&#xff1a;微网 电热联合系统 优化调度 参考文档&#xff1a;《含电热联合系统的微电网运行优化》完全复现 仿真平台&#xff1a;MATLAB yalmipcplex [火]主要内容&#xf…

成都睿趣科技:抖音开网店前期的流程是什么

随着互联网的快速发展&#xff0c;电子商务成为了商业领域中的一大利器&#xff0c;而在电商领域中&#xff0c;抖音作为一个强大的平台&#xff0c;也吸引了众多商家的目光。然而&#xff0c;要在抖音上开设一家成功的网店&#xff0c;并不是一件简单的事情&#xff0c;需要经…

iOS 组件化的三种方案

组件化 本文主要介绍iOS组件化的三种方案 1、常⽤的三种方案 URL SchemeTarget - ActionProtocol - Class 匹配 1.1、 URL Scheme路由 使 URL 处理本地的跳转通过中间层进⾏注册 & 调⽤ &#xff08;load方法里把被调用者注册到中间层&#xff09;注册表⽆需使用反射非…

几个Web自动化测试框架的比较:Cypress、Selenium和Playwright

介绍&#xff1a;Web自动化测试框架对于确保Web应用程序的质量和可靠性至关重要。它们帮助开发人员和测试人员自动执行重复性任务&#xff0c;跨多个浏览器和平台执行测试&#xff0c;并在开发早期发现问题。 本文探讨来3种流行的Web自动化测试框架——Cypress、Selenium和Pla…

WPF中的效果Effect

WPF中的效果Effect 前言 WPF提供了可应用于任何元素的可视化效果。效果的目标是提供一种简便的声明式方法&#xff0c;从而改进文本、图像、按钮以及其他控件的外观。不是编写自己的绘图代码&#xff0c;而是使用某个继承自Effect的类&#xff0c;以立即获得诸如模糊、光辉以…

飞天使-k8s基础组件分析-安全

文章目录 名称空间解释访问kubernetes API的控制RBAC的介绍 kubeconfig用户的创建集群默认角色 给组创建授权针对pod配置服务账户参考文档 名称空间解释 名字是啥&#xff1f; 答&#xff1a;集群中每个对象的名称对于该类型的资源都是唯一的。并且每一个对象在整个集群中也有…

【数据备份、恢复、迁移与容灾】上海道宁与云祺科技为企业用户提供云数据中心容灾备份解决方案

云祺容灾备份系统支持 主流虚拟化环境下的虚拟机备份 提供对云基础设施 云架构平台以及 应用系统的全方位数据保护 云祺容灾备份系统规范功能 增强决策能力 高效恢复数据至可用状态 有效降低恢复成本 更大限度减少业务中断时间 保障业务可访问性 开发商介绍 成都云祺…