【C++】400行代码搞定图书管理系统

一.说明

功能说明

C++编写,主要功能包含三点

  1. 增加图书
  2. 浏览图书
  3. 删除图书
  4. 查找图书

单机运行,数据存放在"book.dat"中,不涉及数据库和网络。

运行环境

Visual Studio 2019

代码说明

  1. Book.h
  图书构造函数以及成员函数和非成员函数声明
  1. Book.cpp
  图书相关函数的定义
  1. BookManager.cpp
  逻辑代码以及主函数定义

二.代码

Book.h

#pragma once
#define NUM1 128
#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* cName);//设置Isbn编号

	char* GetPrice();//获取图书价格
	void SetPrice(char* cPrice);//设置Isbn编号

	char* GetAuthor();//获取作者姓名
	void SetAuthor(char* cName);//设置作者姓名
	//函数WriteData,DeleteData是类对象读写文件的函数,相当于操作数据库的接口
	void WriteData();
	void DeleteData(int iCount1);
	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<string>
#include<fstream>
#include<iostream>
#include<ostream>
using namespace std;
CBook::CBook(char* cName, char* cIsbn, char* cPrice, char* cAuthor) {
	//构造函数
	strncpy_s(m_cName, cName,NUM1);
	strncpy_s(m_cIsbn,cIsbn,NUM1);
	strncpy_s(m_cPrice, cPrice, NUM2);
	strncpy_s(m_cAuthor, cAuthor, NUM2);

}
char* CBook::GetName() {
	return m_cName;
}
void CBook::SetName(char* cName) {
	strncpy_s(m_cName, cName, NUM1);
}
char* CBook::GetIsbn() {
	return m_cIsbn;
}
void CBook::SetIsbn(char* cIsbn) {
	strncpy_s(m_cIsbn, cIsbn, NUM1);
}
char* CBook::GetPrice() {
	return m_cPrice;
}
void CBook::SetPrice(char* cPrice) {
	strncpy_s(m_cPrice, cPrice, NUM2);
}
char* CBook::GetAuthor() {
	return m_cAuthor;
}
void CBook::SetAuthor(char* cAuthor) {
	strncpy_s(m_cAuthor, cAuthor, NUM2);
}

//成员函数WirteData主要实现将图书对象写入到文件中
void CBook::WriteData() {
	ofstream ofile;
	ofile.open("book.dat", ios::binary|ios::app);
	try {
		ofile.write(m_cName, NUM1);
		ofile.write(m_cIsbn, NUM1);
		ofile.write(m_cPrice, NUM2);
		ofile.write(m_cAuthor, NUM2);
	}
	catch (...) {
		throw("file error occurred!");
		ofile.close();
	}
	ofile.close();
}
//成员函数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::binary);
		ifile.read(cName, NUM1);
		if (ifile.tellg() > 0) {
			strncpy_s(m_cName, cName, NUM1);
		}

		ifile.read(cIsbn, NUM1);
		if (ifile.tellg() > 0) {
			strncpy_s(m_cIsbn, cIsbn, NUM1);
		}

		ifile.read(cPrice, NUM2);
		if (ifile.tellg() > 0) {
			strncpy_s(m_cPrice, cPrice, NUM2);
		}

		ifile.read(cAuthor, NUM2);
		if (ifile.tellg() > 0) {
			strncpy_s(m_cAuthor, cAuthor, NUM2);
		}
	}
	catch (...) {
		throw("file error occurred!");
		ifile.close();
	}
	ifile.close();
}
void CBook::DeleteData(int iCount) {
	long respos;
	int iDataCount = 0;
	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::in | ios::out | ios::trunc);
	file.seekg(0, ios::end);
	respos = file.tellg();
	iDataCount = respos / (NUM1 + NUM1 + NUM2 + NUM2);
	if (iCount<0 && iCount>iDataCount) {
		throw "input error";
	}
	else {
		file.seekg((iCount)*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
		for (int j = 0; j != (iDataCount - iCount); j++) {
			memset(cTempBuf, 0, NUM1 + NUM1 + NUM2 + NUM2);
			file.read(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);
			tmpfile.write(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);
		}
		file.close();
		tmpfile.seekg(0,ios::beg);
		ofile.open("book.dat");
		ofile.seekp((iCount-1)*(NUM1 + NUM1 + NUM2 + NUM2),ios::beg);
		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);
		}
	}
	tmpfile.close();
	ofile.close();
	remove("temp.dat");
}

BookManager.cpp

#include<iostream>
#include<iomanip>
#include<stdlib.h>
#include<conio.h>
#include<string.h>
#include<fstream>
#include<iostream>
#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();//主循环
int main() {
	SetScreenGrid();
	SetSysCaption("图书管理系统");
	MainLoop();
	system("pause>nul");
	return 0;
}
void SetScreenGrid() {
	//设置窗体大小
	char sysSetBuf[80];
	sprintf_s(sysSetBuf, "mode con cols=%d lines=%d", CMD_COLS, CMD_LINES);
	system(sysSetBuf);
}
void SetSysCaption() {
	//设置窗口标题
	system("title Sample");
}
void ClearScreen() {
	system("cls");
}
void SetSysCaption(const char* pText) {
	char sysSetBuff[80];
	sprintf_s(sysSetBuff, "title %s", pText);
	system(sysSetBuff);
}
void ShowWelcome() {
	for (int i = 0; i < 10; i++) {
		cout << endl;
	}
	cout << setw(50);
	cout << "**********************" << endl;
	cout << setw(50);
	cout << "       图书管理系统     " << endl;
	cout << setw(50);
	cout << "**********************" << endl;
}
void ShowRootMenu() {
	cout << setw(43);
	cout << "1 添加图书";
	cout << endl;
	cout << setw(43);
	cout << "2 浏览全部";
	cout << endl;
	cout << setw(43);
	cout << "3 删除图书";
	cout << endl;
	cout << endl;
	cout << setw(42);
	cout << "选择操作:";
}
void WaitUser() {
	int iInputPage = 0;
	cout << "enter 返回主菜单 q 退出" << endl;
	char buf[256];
	gets_s(buf);
	if (buf[0] == 'q') {
		system("exit");
	}
}
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 << "保存成功" << endl;
	WaitUser();
}
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;
		}
	}
}
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" << endl;
	cout << endl;
	cout << setw(5)  <<  "序号";
	cout << setw(22) << "书名" << setw(22) << "ISBN";
	cout << setw(15) << "价格" << setw(15) << "作者";
	cout << endl;
	try {
		ifile.seekg((iCurPage - 1) * 20 * (NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
		if (!ifile.fail()) {
			for (int i = 1; i < 21; i++) {
				memset(inName, 0, 128);
				memset(inIsbn, 0, 128);
				memset(inPrice, 0, 50);
				memset(inAuthor, 0, 50);
				if (bIndex) {
					cout << setw(3) << (iCurPage - 1) * 20 + i;
				}
				ifile.read(inName, NUM1);
				cout << setw(24) << inName;
				ifile.read(inIsbn, NUM1);
				cout << setw(22) << inIsbn;
				ifile.read(inPrice, NUM2);
				cout << setw(15) << inPrice;
				ifile.read(inAuthor, NUM2);
				cout << setw(15) << inAuthor;
				cout << endl;
				if (ifile.tellg() <= 0) {
					bIndex = false;
				}
				else {
					bIndex = true;
				}
			}

		}
		cout << "选择操作:";
	}
	catch (...) {
		cout << "File exception" << endl;
		throw "File exception";
		ifile.close();
	}
	if (iCurPage < iPage) {
		iCurPage = iCurPage + 1;
		WaitView(iCurPage);
	}
	else {
		WaitView(iCurPage);
	}
	ifile.close();
}
long GetFileLength(ifstream &ifs) {
	long tmppos;
	long respos;
	tmppos = ifs.tellg();
	ifs.seekg(0,ios::end);
	respos = ifs.tellg();
	ifs.seekg(tmppos, ios::beg);
	return respos;
}
void DeleteBookFromFile() {
	int iDelCount;
	cout << "请输入删除编号:" << endl;
	cin >> iDelCount;
	CBook tmpbook;
	tmpbook.DeleteData(iDelCount);
	cout << "删除结束" << 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);
	}
}

联系方式

QQ群:705884058
在这里插入图片描述

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Coder .

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值