开发语言:C++
开发环境:VS2017
程序说明:图书管理系统分为三个模块:添加新书、浏览全部、删除图书。
三个文件分别是Book.h(包括Book类的声明)、Book.cpp(包括Book类中各方法的具体实现)、main.cpp(包括主函数及各模块的设计)
图书管理系统主界面如图
添加新书界面
浏览全部
Book.h代码如下
#pragma once
#define NUM1 128 //图书名称和Isbn编号最大长度
#define NUM2 50 //图书价格及作者最大长度
class CBook {
public:
CBook(){} //无参构造方法
CBook(char* cName, char* cIsbn, char* cPrice, char* cAuthor);//有参构造方法
~CBook(){} //析构函数
public:
char* GetName();//获取图书名称
void SetName(char* cName);//设置图书名称
char* GetIsbn();//获取图书ISBN编号
void SetIsbn(char* cIsbn);//设置图书ISBN编号
char* GetPrice();//获取图书价格
void SetPrice(char* cPrice);//设置图书价格
char* GetAuthor();//获取图书作者
void SetAuthor(char* cAuthor);//设置图书作者
void WriteData(); //写入数据
void DeleteData(int iCount); //删除数据
void GetBookFromFile(int iCount); //从文件中读取图书记录
protected:
char m_cName[NUM1];
char m_cIsbn[NUM1];
char m_cPrice[NUM2];
char m_cAuthor[NUM2];
};
Book.cpp代码如下
#include "Book.h"
#include
#include
#include
#include
using namespace std;
CBook::CBook(char* cName, char* cIsbn, char* cPrice, char* cAuthor) {
strncpy(m_cName, cName, NUM1);
strncpy(m_cIsbn, cIsbn, NUM1);
strncpy(m_cPrice, cPrice, NUM2);
strncpy(m_cAuthor, cAuthor, NUM2);
}
char* CBook::GetName() {
return m_cName;
}
void CBook::SetName(char* cName) {
strncpy(m_cName, cName, NUM1);
}
char* CBook::GetIsbn() {
return m_cIsbn;
}
void CBook::SetIsbn(char* cIsbn) {
strncpy(m_cName, cIsbn, NUM1);
}
char* CBook::GetPrice() {
return m_cPrice;
}
void CBook::SetPrice(char* cPrice) {
strncpy(m_cPrice, cPrice, NUM2);
}
char* CBook::GetAuthor() {
return m_cAuthor;
}
void CBook::SetAuthor(char* cAuthor) {
strncpy(m_cAuthor, cAuthor, NUM2);
}
//函数WriteDate,GetBookFromFile,DeleteData是类对象对写文件的函数,相当于操作数据库的接口
void CBook::WriteData() {
ofstream ofile;
ofile.open("book.dat", ios::binary | ios::app);//以二进制格式(binary)打开book.dat, app:每次写操作前均定位到文件末尾
try {
ofile.write(m_cName, NUM1);//写入图书的信息
ofile.write(m_cIsbn, NUM1);
ofile.write(m_cPrice, NUM2);
ofile.write(m_cAuthor, NUM2);
}
catch (...) {//catch(…)能够捕获多种数据类型的异常对象
throw "file error occurred";
ofile.close();
}
ofile.close();
}
//成员函数DeleteData负责将图书信息从文件中删除
void CBook::DeleteData(int iCount) {//删掉第iCount条记录
long respos;
int iDataCount = 0;
/*头文件fstarem定义了3各类型来支持文件IO,ifstream从一个给定文件读取数据,
ofatream向一个给定文件写入数据,以及fstream可以读写给定文件*/
fstream file;
fstream tmpfile;
ofstream ofile;
char cTempBuf[NUM1 + NUM1 + NUM2 + NUM2];
file.open("book.dat", ios::binary | ios::in | ios::out);//二进制/读/写
tmpfile.open("temp.dat", ios::binary | ios::out | ios::in | ios::trunc);
/*seekg()是对输入文件定位,它有两个参数:第一个参数是偏移量,第二个参数是基地址。*/
file.seekg(0, ios::end); //基地址为文件结束处,偏移地址为0,于是指针定位在文件结束处
respos = file.tellg();//返回当前定位指针的位置,也代表着输入流的大小。
iDataCount = respos / (NUM1 + NUM1 + NUM2 + NUM2);//总记录数=文件大小/基本量
if (iCount<0 || iCount>iDataCount) {
throw "Input number error";
}
else {//从第iCount+1条记录开始,将以后的记录先存至中间文件变量tmpfile,后将tmpfile的内容覆盖掉iCount条记录之后的内容,相当于删掉了第iCount条记录
file.seekg((iCount)*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);//基地址为文件头,偏移量为基本量*iCount,即读写指针指向了第iCount条记录的起始位置
for (int j = 0; j < (iDataCount - iCount); j++) {//将第iCount条记录后的记录先存入tmpfile
memset(cTempBuf, 0, NUM1 + NUM1 + NUM2 + NUM2);//将cTempBuf清零
file.read(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);//将file中的一条记录读入cTempBuf
tmpfile.write(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);//将cTempBuf中的一条记录写入tmpfile
}
file.close();
tmpfile.seekg(0, ios::beg);//将指针定位在文件头
ofile.open("book.dat");
ofile.seekp((iCount - 1)*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);//将指针定位到第iCount-1条记录的结束位置
for (int i = 0; i < (iDataCount - iCount); i++) {
memset(cTempBuf, 0, NUM1 + NUM1 + NUM2 + NUM2);
tmpfile.read(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);
ofile.write(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);//将cTempBuf中的一条记录写入ofile
}
}
tmpfile.close();
ofile.close();
remove("temp.dat");
}
//成员函数GetBookFromFile从文件中读取数据来构建对象
void CBook::GetBookFromFile(int iCount) {
char cName[NUM1];
char cIsbn[NUM1];
char cPrice[NUM2];
char cAuthor[NUM2];
ifstream ifile;
ifile.open("book.dat", ios::binary);
try {
ifile.seekg(iCount*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
ifile.read(cName, NUM1);
if (ifile.tellg() > 0)
strncpy(m_cName, cName, NUM1);
ifile.read(cIsbn, NUM1);
if (ifile.tellg() > 0)
strncpy(m_cIsbn, cIsbn, NUM1);
ifile.read(cPrice, NUM2);
if (ifile.tellg() > 0)
strncpy(m_cPrice, cPrice, NUM2);
ifile.read(cAuthor, NUM2);
if (ifile.tellg() > 0)
strncpy(m_cAuthor, cAuthor, NUM2);
}
catch (...) {
throw "file error occured";
ifile.close();
}
ifile.close();
}
main.cpp代码如下
#include
#include
#include
#include
#include
#include
#include "Book.h"
#define CMD_COLS 80
#define CMD_LINES 25
using namespace std;
void SetScreenGrid();//设置屏幕显示的行数和列数
void ClearScreen();//清除屏幕信息
void SetSysCaption(const char *pText);//设置窗体标题栏
void ShowWelcome();//显示欢迎信息
void ShowRootMenu();//显示开始菜单
void WaitView(int iCurPage);//浏览数据时等待用户操作
void WaitUser();//等待用户操作
void GuideInput();//使用向导添加图书信息
int GetSelect();//获得用户菜单选择
long GetFileLength(ifstream &ifs);//获取文件长度
void ViewData(int iSelPage);//浏览所有图书记录
void DeleteBookFromFile();//在文件中产生图书信息
void mainloop();//主循环
void main()
{
SetScreenGrid();
SetSysCaption("图书管理系统");
mainloop();
}
void SetScreenGrid() {
char sysSetBuf[80];
sprintf(sysSetBuf, "mode con cols=%d lines=%d", CMD_COLS, CMD_LINES);
system(sysSetBuf);
}
void SetSysCaption()
{
system("title Sample");
}
void SetSysCaption(const char *pText)
{
char sysSetBuf[80];
sprintf(sysSetBuf, "title %s", pText);
system(sysSetBuf);
}
void ClearScreen() {
system("cls");
}
void ShowWelcome() {
for (int i = 0; i < 7; i++) {
cout << endl;
}
cout << setw(40);
cout << "******************" << endl;
cout << setw(40);
cout << "***图书管理系统***" << endl;
cout << setw(40);
cout << "******************" << endl;
}
void ShowRootMenu() {
cout << setw(35);
cout << "请选择功能" << endl;
cout << endl;
cout << setw(35);
cout << "1 添加新书" << endl;
cout << endl;
cout << setw(35);
cout << "2 浏览全部" << endl;
cout << endl;
cout << setw(35);
cout << "3 删除图书" << endl;
cout << endl;
}
void WaitUser() {
int iInputPage = 0;
cout << "enter 返回主菜单 q退出" << endl;
char buf[256];
gets_s(buf);
if (buf[0] == 'q')
system("exit");
}
void mainloop(){
ShowWelcome();
while (1) {
ClearScreen();
ShowWelcome();
ShowRootMenu();
switch (GetSelect()) {
case 1:
ClearScreen();
GuideInput();
break;
case 2:
ClearScreen();
ViewData(1);
break;
case 3:
ClearScreen();
DeleteBookFromFile();
break;
}
}
}
int GetSelect() {
char buf[256];
gets_s(buf);
return atoi(buf);
}
void GuideInput() {
char inName[NUM1];
char inIsbn[NUM1];
char inPrice[NUM2];
char inAuthor[NUM2];
cout << "输入书名" << endl;
cin >> inName;
cout << "输入Isbn" << endl;
cin >> inIsbn;
cout << "输入价格" << endl;
cin >> inPrice;
cout << "输入作者" << endl;
cin >> inAuthor;
CBook book(inName, inIsbn, inPrice, inAuthor);
book.WriteData();
cout << "Write Finish" << endl;
WaitUser();
}
void ViewData(int iSelPage=1)//浏览图书
{
int iPage = 0;//总页数
int iCurPage = 0;//当前页数
int iDataCount = 0;//总书数
char inName[NUM1];
char inIsbn[NUM1];
char inPrice[NUM2];
char inAuthor[NUM2];
bool bIndex = false;
int iFileLength;
iCurPage = iSelPage;
ifstream ifile;
ifile.open("book.dat", ios::binary);
iFileLength = GetFileLength(ifile);
iDataCount = iFileLength / (NUM1 + NUM1 + NUM2 + NUM2);//根据文件长度,计算文件中总记录数
if (iDataCount >= 1)
bIndex = true;
iPage = iDataCount / 20 + 1;
ClearScreen();//清除屏幕信息
cout << "共有记录" << iDataCount << " ";
cout << "共有页数" << iPage << " ";
cout << "当前页数" << iCurPage << " ";
cout << "n 显示下一页 m 返回" <> iDelCount;
CBook tmpbook;
tmpbook.DeleteData(iDelCount);
cout << "Delete Finish" << endl;
WaitUser();
}
void WaitView(int iCurPage)
{
char buf[256];
gets_s(buf);
if (buf[0] == 'q')
system("exit");
if (buf[0] == 'm')
mainloop();
if (buf[0] == 'n')
ViewData(iCurPage);
}