序列化实例

#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;
}


你可能感兴趣的:(struct,File,null,delete,Random,include)