#include <stdlib.h>
#include<stdlib.h>
#include<time.h>
#define random(x) (rand()%x)
#define OUT
#define IN
typedef struct _XY
{
int nX;
struct _XY* pNext;
}XY,* PXY;
typedef struct _MyStruct
{
int nA;
char cB; PXY pXY; struct _MyStruct* pLNext;
struct _MyStruct* pRNext;
}MYSTRUCT, *PMYSTRUCT;
// 下面字符代表有指针数据
static unsigned char uszBufPointer[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
// 下面字符代表有指针结束
static unsigned char uszBufEnd[8] = {0x00, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
// 递归序列化
void serialIn(PMYSTRUCT pList, FILE* pFile)
{
if (pList == NULL)
{
// 写入不存在后续指针标志
fwrite(uszBufEnd, 1, 8, pFile);
return;
}
// 写入存在后续指针标志
fwrite(uszBufPointer, 1, 8, pFile);
// 写入常量
fwrite(pList, 1, 5, pFile); // 先写入5个字节 int + char
// 写入pXY结构体
PXY pXY = pList->pXY;
while (pXY != NULL)
{
// 写入存在后续指针标志
fwrite(uszBufPointer, 1, 8, pFile);
// 写入数据
fwrite(&(pXY->nX), 1, 4, pFile);
pXY = pXY->pNext;
}
// 写入结束标志
fwrite(uszBufEnd, 1, 8, pFile);
// 写入左子树
serialIn(pList->pLNext, pFile);
// 写入结束标志
fwrite(uszBufEnd, 1, 8, pFile);
// 写入右子树
serialIn(pList->pRNext, pFile);
// 写入结束标志
fwrite(uszBufEnd, 1, 8, pFile);
}
// 序列化写入文件,-1代表失败
int serialInToFile(IN PMYSTRUCT pList, IN const char* pFileName)
{
int nReturn = -1;
FILE* pFile = fopen(pFileName, "wb+");
if (!pFile)
return nReturn;
// 递归序列化
serialIn(pList, pFile);
fclose(pFile);
nReturn = 1;
return nReturn;
}
unsigned char szBuf[8] = {0};
// 判断是否有下一个指针域
int judgeIfHaveNextPointer(unsigned char* pBuf)
{
int nReturn = 0;
int i = 0;
for (i = 0; i < 8; i ++)
if (pBuf[i] != 0x00)
break;
if (i != 8) // 说明可能有指针域
{
for (i = 0; i < 8; i ++)
if (pBuf[i] != 0xff)
break;
if (i == 8) // 有指针域
{
nReturn = 1;
return nReturn;
}
}
else
return nReturn;
return nReturn;
}
unsigned char uszTmpBuf[5] = {0};
// 递归读入
void serialRead(OUT PMYSTRUCT* ppList, FILE* pFile)
{
// 首先读8个字节判断是否有下一个节点
fread(szBuf, 1, 8, pFile);
int nTmp = judgeIfHaveNextPointer(szBuf);
if (nTmp == 0)
return;
// 声明指针域
*ppList = new MYSTRUCT;
(*ppList)->pXY = NULL;
(*ppList)->pLNext = NULL;
(*ppList)->pRNext = NULL;
// 先读入5个字节, int + char
fread(uszTmpBuf, 1, 5, pFile);
int* pInteger = (int*) uszTmpBuf;
(*ppList)->nA = *pInteger;
char* pChar = (char*) (uszTmpBuf + 4);
(*ppList)->cB = *pChar;
// 获取pXY区域
fread(szBuf, 1, 8, pFile);
nTmp = judgeIfHaveNextPointer(szBuf);
if(nTmp == 1)
{
(*ppList)->pXY = new XY;
PXY pXY = (*ppList)->pXY;
do
{
pXY->pNext = NULL;
// 读取4个字节 int
fread(uszTmpBuf, 1, 4, pFile);
pInteger = (int*) uszTmpBuf;
pXY->nX = *pInteger;
fread(szBuf, 1, 8, pFile);
nTmp = judgeIfHaveNextPointer(szBuf);
if (nTmp == 1)
{
pXY->pNext = new XY;
pXY = pXY->pNext;
}
} while (nTmp == 1);
}
// 左孩子指针
serialRead(&((*ppList)->pLNext), pFile);
fread(szBuf, 1, 8, pFile);
// 右孩子指针
serialRead(&((*ppList)->pRNext), pFile);
fread(szBuf, 1, 8, pFile);
}
// 序列化读入文件,-1代表失败
int serialOutFromeFile(OUT PMYSTRUCT* ppList, IN const char* pFileName)
{
int nReturn = -1;
FILE* pFile = fopen(pFileName, "rb");
PMYSTRUCT pCurNode = (PMYSTRUCT)malloc(sizeof(MYSTRUCT));
unsigned char uszBuf[8] = {0};
int i = 0;
int* pA = NULL;
if (!pFile)
return nReturn;
serialRead(ppList, pFile);
fclose(pFile);
nReturn = 1;
return nReturn;
}
// 初始化成为一个复杂的结构系统
void InitStruct(PMYSTRUCT pSTest, int nA)
{
pSTest->pXY = NULL;
pSTest->pLNext = NULL;
pSTest->pRNext = NULL;
if (nA == 0)
{
pSTest->nA = 0;
pSTest->cB = 0;
return;
}
// 撒下随机数种子,产生一个20以内的随机数
srand((int)time(0));
int nRand = random(20);
// 赋值
pSTest->nA = nRand;
if (nRand > 10)
pSTest->cB = 'A' + nRand;
else
pSTest->cB = 'a' + nRand;
// 自带的结构体
pSTest->pXY = new XY;
PXY pXY = pSTest->pXY;
pXY->pNext = NULL;
for(int i = 0; i < nRand / 4; i ++)
{
pXY->nX = nRand - i;
pXY->pNext = new XY;
pXY = pXY->pNext;
pXY->pNext = NULL;
}
pXY->nX = nRand + 1;
pXY->pNext = NULL;
// 对于两个左右节点赋值
pSTest->pLNext = new MYSTRUCT;
InitStruct(pSTest->pLNext, nA - 1);
pSTest->pRNext = new MYSTRUCT;
InitStruct(pSTest->pRNext, nA - 1);
}
// 递归删除
void DeleteStruct(PMYSTRUCT pSTest)
{
if(pSTest == NULL)
return;
PXY pXY = pSTest->pXY;
while (pXY != NULL)
{
PXY pTmp = pXY;
pXY = pXY->pNext;
delete pTmp;
}
pSTest->pXY = NULL;
// 删除左右子树
DeleteStruct(pSTest->pLNext);
pSTest->pLNext = NULL;
DeleteStruct(pSTest->pRNext);
pSTest->pRNext = NULL;
// 删除自己
delete pSTest;
}
// 递归打印数据
void printStruct(PMYSTRUCT pSTest,int nNum)
{
if(pSTest == NULL)
{
printf("NULL");
return;
}
printf("/n 第%d层节点数据/n", nNum);
printf("nA = %d, cB = %c XY---> ", pSTest->nA, pSTest->cB);
int i = 0;
PXY pXY = pSTest->pXY;
while (pXY != NULL)
{
++i;
printf("第%d个XY, nX = %d ---> ", i, pXY->nX);
pXY = pXY->pNext;
}
printf("NULL");
// 打印子节点
printf("/n打印下一层左孩子节点");
printStruct(pSTest->pLNext, nNum + 1);
printf("/n打印下一层右孩子节点");
printStruct(pSTest->pRNext, nNum + 1);
}
int main(int argc, _TCHAR* argv[])
{
int nReturn = 0;
const char* pFileName = "fileSerial.tmp";
const char* pFileName2 = "fileSerial2.tmp";
PMYSTRUCT pSTest = new MYSTRUCT;
// 初始化
InitStruct(pSTest, 5); // 2层比较好调试,5层
// 打印
printStruct(pSTest, 0);
// 序列化
serialInToFile(pSTest, pFileName);
// 删除
DeleteStruct(pSTest);
pSTest = NULL;
// 导出序列化
serialOutFromeFile(&pSTest, pFileName);
// 打印
printf("/n/n---------------------------------/n");
printStruct(pSTest, 0);
// 再次序列化,对比内容
serialInToFile(pSTest, pFileName2);
// 删除
DeleteStruct(pSTest);
getchar();
return 0;
}
序列化实例
最新推荐文章于 2021-09-15 22:16:07 发布