类示意图
select类示意图
cFile类示意图
ListStu类示意图
ClassStu示意图
项目源代码
select
select.h
#pragma once
#include <iostream>
#include "classstu.h"
#include <iomanip>
#include "cfile.h"
#include "ListStu.h"
using namespace std;
class Select
{
public:
Select()
{
m_pFile = nullptr;
m_pListStu = nullptr;
}
Select(const char* filename) :m_pFile(new cFile(filename))
{
int nCount = m_pFile->ReadFileHeader();
m_pListStu = new ListStu(nCount);
m_pFile->ReadFileAllDate(m_pListStu);
}
~Select();
void SelectAllDate();
bool FindOneDate(int nUserId);
void DrawOneDate(ListStu::Iterator itr);
int SelectFileOffOneDateId(int userid);
bool InsertOneDate(const char* susername,int nId = 0);
bool DeleteDate(int id);
bool UpDate(const char* susername, int nuserid);
void DrawInit();
void DrawHead();
int IdEmptyFill(int id);
bool GetFlg();
bool ReDEFile(const char* old_filename, const char* new_filename);
public:
cFile* m_pFile;
ListStu* m_pListStu;
bool m_flg = false;
};
select.cpp
#include "Select.h"
void Select::SelectAllDate()
{
DrawHead();
m_pListStu->insertionSort();
int nIndex = 1;
for (auto Val : *m_pListStu)
{
cout << nIndex << setw(14 - (IdEmptyFill(nIndex))) << " ";
cout << Val.m_Id << setw(8 - (IdEmptyFill(Val.m_Id))) << " ";
cout << Val.m_StuName->GetStr() << setw(14 - ((Val.m_StuName->GetLen()))) << " ";
cout << Val.m_FileOffset << endl;
nIndex++;
}
}
bool Select::FindOneDate(int nUserId)
{
if (nUserId < 0)
{
return false;
}
int nIndex = m_pListStu->UserIdToIndex(nUserId);
if (nIndex == -1)
{
cout << "没有此用户" << endl;
return false;
}
ListStu::Iterator Itr = m_pListStu->FindItr(nIndex);
DrawOneDate(Itr);
return true;
}
void Select::DrawOneDate(ListStu::Iterator Itr)
{
DrawHead();
cout << (*Itr).m_Id << setw(8 - IdEmptyFill((*Itr).m_Id)) << " ";
cout << (*Itr).m_StuName->GetStr()<< setw(14 - (*Itr).m_StuName->GetLen()) << " ";
cout << (*Itr).m_FileOffset << endl;
}
int Select::SelectFileOffOneDateId(int UserId)
{
if (UserId <= 0)
{
return 0;
}
for(auto Val:*m_pListStu)
{
if (UserId == Val.m_Id)
{
return Val.m_FileOffset;
}
}
return 0;
}
bool Select::InsertOneDate(const char* sUserName, int nUserId)
{
if (sUserName == nullptr)
{
cout << "sUserName写入失败" << endl;
return false;
}
if(nUserId == 0)
{
nUserId = m_pListStu->GetMaxUserId();
nUserId++;
}
ClassStu* cTmp = new ClassStu(nUserId, sUserName);
m_pFile->WriteInsertFile(cTmp);
if (cTmp == nullptr)
{
cout << "ClassStu* cTmp写入失败" << endl;
return false;
}
m_pListStu->VailInsert(*cTmp);
delete cTmp;
return true;
}
bool Select::DeleteDate(int nId)
{
int nIndex = nId - 1;
int FileOffset = m_pListStu->FindFOffset(nIndex);
if (!FileOffset == 0)
{
if (m_pFile->WriteDeleteFile(FileOffset) == 1)
{
m_pListStu->DeteleId(nIndex);
m_flg = true;
return m_flg;
}
}
return false;
}
bool Select::UpDate(const char* sUserName, int nId)
{
nId--;
if (sUserName == nullptr)
{
return false;
}
int nUserId = m_pListStu->FindId(nId);
ClassStu* cStu = new ClassStu(nUserId, sUserName);
if (!m_pFile->WriteInsertFile(cStu))
{
return false;
}
int nFileOffset = m_pListStu->FindFOffset(nId);
if (m_pFile->WriteDeleteFile(nFileOffset) != 1)
{
return false;
}
m_pListStu->UpDate(nId,*cStu);
m_flg = true;
delete cStu;
return true;
}
void Select::DrawInit()
{
cout << "========" << "欢迎来到电话薄操作" << "========" << endl;
cout << "一:显示所有数据。" << endl;
cout << "二:查询联系人" << endl;
cout << "三:增加联系人。" << endl;
cout << "四:修改联系人。" << endl;
cout << "五:删除联系人。" << endl;
cout << "六:随机拨打任意联系人。" << endl;
cout << "七:退出程序。" << endl;
cout << "请选择操作:" << endl;
}
void Select::DrawHead()
{
cout << "用户序号" << setw(6) << " ";
cout << "用户ID" << setw(4) << " ";
cout << "用户名称" << setw(6) << " ";
cout << "文件偏移" << endl;
}
int Select::IdEmptyFill(int Id)
{
int nCount = 0;
while (Id > 9) {
Id = Id / 10;
nCount++;
}
return nCount;
}
bool Select::GetFlg()
{
return m_flg;
}
bool Select::ReDEFile(const char* old_filename, const char* new_filename)
{
return m_pFile->ReDeFileName(old_filename, new_filename, m_pListStu);
}
Select::~Select()
{
delete m_pListStu;
delete m_pFile;
}
cFile
cFile.h
#pragma once
#include <iostream>
#include "ListStu.h"
#include "VetorCstu.h"
using namespace std;
class cFile
{
public:
enum FileType { WRITEERR = -3, READERR, PNULL , SUCCESS = 1 };
public:
cFile();
cFile(const char* FileName);
cFile(const cFile& fFile);
~cFile();
int ReadFileHeader();
FileType ReadFileAllDate(ListStu* Cstu);
bool WriteInsertFile(ClassStu* cStu);
int WriteDeleteFile(int FileOffset);
FileType UpDateHeader(bool bTmp = true);
bool ReDeFileName(const char* old_filename, const char* new_filename, ListStu* Cstu);
int WriteFileAllDate(ListStu* Cstu);
int WriteOneDate(ClassStu* cStu);
void CloseFile();
private:
bool IsOpen();
FileType WriteFileDate(void* buffer, int nSize);
FileType ReadFileDate(void* buffer, int nSize);
private:
FILE* m_pFile;
int* m_nCount;
};
cFile.cpp
#include "cFile.h"
cFile::cFile(const cFile& fFile)
{
m_pFile = nullptr;
m_nCount = NULL;
if (fFile.m_pFile != nullptr)
{
m_pFile = fFile.m_pFile;
m_nCount = fFile.m_nCount;
(*m_nCount)++;
}
}
cFile::cFile()
{
m_pFile = nullptr;
m_nCount = nullptr;
}
cFile::cFile(const char* FileName)
{
fopen_s(&m_pFile, FileName, "r+b");
m_nCount = new int(0);
if (!IsOpen())
{
fopen_s(&m_pFile, FileName, "w+b");
if (WriteFileDate(m_nCount, 4) != SUCCESS)
{
cout << "初始化失败" << endl;
}
fflush(m_pFile);
}
}
cFile::~cFile()
{
if (m_pFile == nullptr)
{
return;
}
if (*m_nCount != 0)
{
(*m_nCount)--;
}
else
{
CloseFile();
cout << "关闭文件成功" << endl;
}
}
bool cFile::IsOpen()
{
if (m_pFile == nullptr)
{
return false;
}
return true;
}
int cFile::ReadFileHeader()
{
rewind(m_pFile);
int nCount = 0;
if (fread((char*)&nCount, 1, 4, m_pFile) == 4)
{
return nCount;
}
return 0;
}
cFile::FileType cFile::ReadFileAllDate(ListStu* Cstu)
{
if (Cstu == nullptr)
{
return PNULL;
}
for (auto Itr = Cstu->begin(); Itr != Cstu->end(); ++Itr)
{
(*Itr).Deserialize(m_pFile);
}
return SUCCESS;
}
cFile::FileType cFile::ReadFileDate(void* buffer, int nSize)
{
if (buffer == nullptr || nSize <= 0)
{
return READERR;
}
if (fread(buffer, 1, nSize, m_pFile) == nSize)
{
return SUCCESS;
}
return READERR;
}
bool cFile::WriteInsertFile(ClassStu* cStu)
{
if(cStu == nullptr)
{
return false;
}
if (WriteOneDate(cStu)!= SUCCESS)
{
return false;
}
UpDateHeader();
if (fflush(m_pFile) != 0)
{
cout << "写入文件失败" << endl;
return false;
}
return true;
}
int cFile::WriteDeleteFile(int FileOffset)
{
fseek(m_pFile, FileOffset, SEEK_SET);
int a = 0;
if (WriteFileDate(&a, 4) != SUCCESS)
{
return WRITEERR;
}
fflush(m_pFile);
return SUCCESS;
}
cFile::FileType cFile::WriteFileDate(void* buffer, int nSize)
{
if (buffer == nullptr || nSize <= 0)
{
return WRITEERR;
}
if (fwrite(buffer, 1, nSize, m_pFile) == nSize)
{
return SUCCESS;
}
return WRITEERR;
}
void cFile::CloseFile()
{
fclose(m_pFile);
delete m_nCount;
m_nCount = nullptr;
m_pFile = nullptr;
}
bool cFile::ReDeFileName(const char* old_filename, const char* new_filename, ListStu* Cstu)
{
CloseFile();
if (rename(old_filename, new_filename) == 0)
{
cFile FileStuu(old_filename);
if (FileStuu.WriteFileAllDate(Cstu) == 1)
{
remove("mystudate_old.bin");
return true;
}
}
return false;
}
int cFile::WriteFileAllDate(ListStu* Cstu)
{
int nNewCount = 0;
for (ClassStu Val : *Cstu)
{
if (Val.m_Id != 0)
{
if (WriteOneDate(&Val) != SUCCESS)
{
return WRITEERR;
}
nNewCount++;
}
}
fseek(m_pFile,0,SEEK_SET);
if (WriteFileDate(&nNewCount, 4) != SUCCESS)
{
return WRITEERR;
}
fflush(m_pFile);
return SUCCESS;
}
int cFile::WriteOneDate(ClassStu* cStu)
{
if (cStu == nullptr)
{
return WRITEERR;
}
if (!cStu->Serialize(m_pFile))
{
return WRITEERR;
}
return SUCCESS;
}
cFile::FileType cFile::UpDateHeader(bool bTmp)
{
int nCount = ReadFileHeader();
if (nCount == -1)
{
return READERR;
}
bTmp ? nCount++ : nCount--;
fseek(m_pFile,0,SEEK_SET);
if (WriteFileDate(&nCount, 4) != SUCCESS)
{
return WRITEERR;
}
fflush(m_pFile);
return SUCCESS;
}
ListStu
ListStu.h
#pragma once
#include "ClassStu.h"
class ListStu
{
public:
struct StuNode
{
ClassStu cStu;
StuNode* pNext;
StuNode()
{
pNext = nullptr;
}
};
using pStuNode = StuNode*;
public:
class Iterator
{
public:
Iterator(pStuNode Head, pStuNode Vail)
{
m_Head = Head;
m_Vail = Vail;
}
ClassStu& operator*()
{
return m_Head->cStu;
}
Iterator& operator++()
{
if (m_Head != m_Vail->pNext)
{
m_Head = m_Head->pNext;
}
return *this;
}
bool operator!=(Iterator Itr)
{
return m_Head != Itr.m_Head->pNext;
}
private:
pStuNode m_Head;
pStuNode m_Vail;
};
public:
ListStu();
ListStu(int nCount);
~ListStu();
ListStu& HeadInsert(ClassStu& cStu);
ListStu& VailInsert(ClassStu& cStu);
ListStu& Insert(pStuNode PosNode,ClassStu& cStu);
void Detele(pStuNode PosNode);
void DeteleId(int nIndex);
void DeteleHead();
StuNode* Find(int nIndex);
Iterator FindItr(int nIndex);
int FindFOffset(int nIndex);
int FindId(int nIndex);
int UserIdToIndex(int UserId);
void UpDate(int nIndex,ClassStu& cStu);
Iterator begin()
{
return Iterator(m_HeaderStu, m_VailStu);
}
Iterator end()
{
return Iterator(m_VailStu, m_VailStu);
}
void InitList();
int GetMaxUserId();
int Size();
void insertionSort();
private:
pStuNode m_HeaderStu;
pStuNode m_VailStu;
int m_nCount;
};
ListStu.cpp
#include "ListStu.h"
ListStu::ListStu()
{
InitList();
}
ListStu::ListStu(int nCount)
{
InitList();
for (int i = 0; i < nCount; i++)
{
ClassStu cStu;
VailInsert(cStu);
}
}
ListStu::~ListStu()
{
if (m_nCount == 0)
{
return;
}
pStuNode TmpbNode = m_HeaderStu;
pStuNode TmpfNode = nullptr;
for (int i = 0; i < m_nCount; i++)
{
TmpfNode = TmpbNode->pNext;
delete TmpbNode;
TmpbNode = TmpfNode;
}
}
ListStu& ListStu::HeadInsert(ClassStu& cStu)
{
if (m_nCount == 0)
{
m_HeaderStu->cStu = cStu;
m_VailStu = m_HeaderStu;
m_nCount++;
return *this;
}
pStuNode pNewNode = new StuNode;
pNewNode->cStu = cStu;
pNewNode->pNext = m_HeaderStu;
m_HeaderStu = pNewNode;
m_nCount++;
return *this;
}
ListStu& ListStu::VailInsert(ClassStu& cStu)
{
return Insert(m_VailStu, cStu);
}
ListStu& ListStu::Insert(pStuNode PosNode, ClassStu& cStu)
{
if (m_nCount == 0)
{
return HeadInsert(cStu);
}
pStuNode pNewNode = new StuNode;
pNewNode->cStu = cStu;
pNewNode->pNext = PosNode->pNext;
PosNode->pNext = pNewNode;
if (PosNode == m_VailStu)
{
m_VailStu = pNewNode;
}
m_nCount++;
return *this;
}
void ListStu::Detele(pStuNode PosNode)
{
if (PosNode->pNext == m_VailStu)
{
m_VailStu = PosNode;
}
pStuNode DeleteNode = PosNode->pNext;
PosNode->pNext = DeleteNode->pNext;
delete DeleteNode;
m_nCount--;
}
void ListStu::DeteleId(int nIndex)
{
if (nIndex == 0)
{
DeteleHead();
return;
}
--nIndex;
pStuNode bDeleteNode = Find(nIndex);
Detele(bDeleteNode);
}
void ListStu::DeteleHead()
{
pStuNode DeleteNode = m_HeaderStu;
m_HeaderStu = m_HeaderStu->pNext;
delete DeleteNode;
m_nCount--;
}
ListStu::StuNode* ListStu::Find(int nIndex)
{
if (m_nCount < 1 ||nIndex < 0 || nIndex > m_nCount)
{
return nullptr;
}
pStuNode FindNode = m_HeaderStu;
for (int i = 0; i < nIndex; i++)
{
FindNode = FindNode->pNext;
}
return FindNode;
}
ListStu::Iterator ListStu::FindItr(int nIndex)
{
return Iterator(Find(nIndex),m_VailStu);
}
int ListStu::FindFOffset(int nIndex)
{
pStuNode pFindNode = Find(nIndex);
if (pFindNode == nullptr)
{
return 0;
}
return pFindNode->cStu.m_FileOffset;
}
int ListStu::FindId(int nIndex)
{
pStuNode pFindNode = Find(nIndex);
if (pFindNode == nullptr)
{
return 0;
}
return pFindNode->cStu.m_Id;
}
int ListStu::UserIdToIndex(int UserId)
{
int nIndex = 0;
for (auto Val : *this)
{
if (UserId == Val.m_Id)
{
return nIndex;
}
nIndex++;
}
return -1;
}
void ListStu::UpDate(int nIndex, ClassStu& cStu)
{
pStuNode pUpDate = Find(nIndex);
pUpDate->cStu = cStu;
}
void ListStu::InitList()
{
m_HeaderStu = new StuNode;
m_VailStu = nullptr;
m_nCount = 0;
}
int ListStu::GetMaxUserId()
{
int nMaxId = 1;
for (auto Val:*this)
{
if (nMaxId < Val.m_Id)
{
nMaxId = Val.m_Id;
}
}
return nMaxId;
}
int ListStu::Size()
{
return m_nCount;
}
void ListStu::insertionSort()
{
pStuNode sorted = NULL;
pStuNode current = m_HeaderStu;
while (current != NULL) {
pStuNode next = current->pNext;
pStuNode prev = NULL;
pStuNode last = sorted;
while (last != NULL && last->cStu.m_Id < current->cStu.m_Id) {
prev = last;
last = last->pNext;
}
current->pNext = last;
if (prev == NULL) {
sorted = current;
}
else {
prev->pNext = current;
}
if (last == nullptr)
{
m_VailStu = current;
}
current = next;
}
m_HeaderStu = sorted;
}
ClassStu
ClassStu.h
#pragma once
#include "ClassStr.h"
class ClassStu
{
public:
ClassStu();
ClassStu(ClassStu& cStu);
ClassStu(int Id, const char* Name, int FileOffset = 0);
ClassStu(int Id, MyStr* cStr, int FileOffset = 0);
~ClassStu();
void operator=(ClassStu* cStu);
ClassStu& operator=(ClassStu& cStu);
char* operator*();
bool operator== (void* pVoid);
bool IsEmpty();
void InitClass();
void IsClear();
bool Serialize(FILE* pFile);
bool Deserialize(FILE* pFile);
public:
int m_Id;
MyStr* m_StuName;
int m_FileOffset;
int* m_nIndex;
};
ClassStu.cpp
#include "ClassStu.h"
ClassStu::ClassStu()
{
InitClass();
}
ClassStu::ClassStu(ClassStu& cStu)
{
if (cStu == nullptr || cStu.m_StuName == m_StuName)
{
InitClass();
return;
}
if (cStu.m_nIndex == nullptr)
{
cStu.m_nIndex = new int(0);
}
m_Id = cStu.m_Id;
m_FileOffset = cStu.m_FileOffset;
m_StuName = cStu.m_StuName;
m_nIndex = cStu.m_nIndex;
(*m_nIndex)++;
}
ClassStu::ClassStu(int Id, const char* Name, int FileOffset)
{
if (Name == nullptr)
{
InitClass();
return;
}
m_StuName = new MyStr(Name);
m_nIndex = new int(0);
m_Id = Id;
m_FileOffset = FileOffset;
}
ClassStu::ClassStu(int Id, MyStr* cStr, int FileOffset)
{
if (cStr == nullptr)
{
InitClass();
return;
}
m_StuName = cStr;
m_nIndex = new int(0);
m_Id = Id;
m_FileOffset = FileOffset;
}
ClassStu::~ClassStu()
{
IsClear();
}
void ClassStu::operator=(ClassStu* cStu)
{
if (cStu == nullptr || cStu->m_StuName == m_StuName)
{
InitClass();
return;
}
if (cStu->m_nIndex == nullptr)
{
cStu->m_nIndex = new int(0);
}
IsClear();
m_Id = cStu->m_Id;
m_FileOffset = cStu->m_FileOffset;
m_StuName = cStu->m_StuName;
m_nIndex = cStu->m_nIndex;
(*m_nIndex)++;
}
ClassStu& ClassStu::operator=(ClassStu& cStu)
{
if (cStu == nullptr || cStu.m_StuName == m_StuName)
{
return *this;
}
if (cStu.m_nIndex == nullptr)
{
cStu.m_nIndex = new int(0);
}
IsClear();
m_Id = cStu.m_Id;
m_FileOffset = cStu.m_FileOffset;
m_StuName = cStu.m_StuName;
m_nIndex = cStu.m_nIndex;
(*m_nIndex)++;
return *this;
}
char* ClassStu::operator*()
{
return m_StuName->GetStr();
}
bool ClassStu::operator==(void* pVoid)
{
if (this == nullptr)
{
return true;
}
return false;
}
bool ClassStu::IsEmpty()
{
return m_StuName->GetStr() != nullptr;
}
void ClassStu::InitClass()
{
m_StuName = nullptr;
m_nIndex = nullptr;
m_Id = 0;
m_FileOffset = 0;
}
void ClassStu::IsClear()
{
if (m_StuName == nullptr)
{
return;
}
if (*m_nIndex != 0)
{
(*m_nIndex)--;
return;
}
cout << "m_StuName" << m_Id << endl;
delete m_nIndex;
delete m_StuName;
}
bool ClassStu::Serialize(FILE* pFile)
{
fseek(pFile, 0, SEEK_END);
int FileOffset = ftell(pFile);
m_FileOffset = FileOffset;
if (FileOffset == -1L)
{
return false;
}
if (fwrite(&m_Id, 1, 4, pFile) != 4)
{
return false;
}
char nLen = m_StuName->GetLen();
if (fwrite(&nLen, 1, 1, pFile) != 1)
{
return false;
}
if (fwrite(m_StuName->GetStr(), 1, nLen, pFile) != nLen)
{
return false;
}
if (fwrite(&FileOffset, 1, 4, pFile) != 4)
{
return false;
}
return true;
}
bool ClassStu::Deserialize(FILE* pFile)
{
if (fread(&m_Id, 1, 4, pFile) != 4)
{
return false;
}
char nLen = 0;
if (fread(&nLen,1, 1, pFile) != 1)
{
return false;
}
m_StuName = new MyStr(nLen);
if (fread(m_StuName->GetStr(), 1, nLen, pFile) != nLen)
{
return false;
}
if (fread(&m_FileOffset, 1, 4, pFile) != 4)
{
return false;
}
return true;
}
main 源码
#include "Select.h"
#include <conio.h>
int main()
{
Select MySele2("mystudate.bin");
int selectId = 0;
while (selectId != 7)
{
system("cls");
MySele2.DrawInit();
scanf_s("%d", &selectId);
if (selectId < 0 || selectId > 7)
{
cout << "输入错误,请重新输入" << endl;
continue;
}
switch (selectId)
{
case 1:
{
MySele2.SelectAllDate();
break;
}
case 2:
{
int nUserId = 0;
cout << "请输入用户Id:" << endl;
scanf_s("%d",&nUserId);
MySele2.FindOneDate(nUserId);
break;
}
case 3:
{
char sUserName[32] = { 0 };
memset(sUserName, 0, 32);
cout << "请输入姓名:" << endl;
scanf_s("%s", sUserName, 32);
MySele2.InsertOneDate(sUserName);
break;
}
case 4:
{
char sUserName[32] = { 0 };
memset(sUserName, 0, 32);
int nId = 0;
cout << "请输入要求改的用户序号" << endl;
scanf_s("%d", &nId);
int nSize = MySele2.m_pListStu->Size();
if (nId < 1 || nId > nSize)
{
cout << "删除失败" << endl;
break;
}
cout << "请输入要修改的名字" << endl;
scanf_s("%s", sUserName, 32);
MySele2.UpDate(sUserName, nId);
break;
}
case 5:
{
cout << "请输入要删除的用户序号" << endl;
int nIndex = 0;
scanf_s("%d", &nIndex);
int nSize = MySele2.m_pListStu->Size();
if (nIndex < 1 || nIndex > nSize)
{
cout << "删除失败" << endl;
break;
}
if (MySele2.DeleteDate(nIndex) == false)
{
cout << "删除失败" << endl;
}
}
}
system("pause");
}
if (MySele2.GetFlg())
{
MySele2.ReDEFile("mystudate.bin", "mystudate_old.bin");
}
return 0;
}