C++项目开发全程实录
章 第 1
图
管理系统
11 ,Visual C++ 6.0实现,
随着现代社会的信息量不断增加,图书的种类及信息也越来越多,
如何管理庞大的图书信息成为图书管理工作中的一大难题。在计算机
信息技术高速发展的今天,人们意识到原有的人工管理方式已经不能
适应社会,而使用计算机信息系统来管理已是最有效率的一种手段。
通过学习本章,读者可以学到,
, 了解软件整体
, 掌握类的实际应用
, 掌握分页数据浏览
, 掌握文件存储数据
章导第
读
C++项目开发全程实录
1.1 开 发 背 景
随着现代图书市场竞争愈演愈烈,如何以一种便捷的管理方式加快图书流通信息的反馈速度,降低图书库存占用,缩短资金周转时间,提高工作效率,已经成为能否增强图书企业竞争力的关键。信息技术的飞速发展给图书企业的管理带来了全新的变革,采用图书管理系统对图书企业的经营运作进行全程管理,不仅使企业摆脱了以往人工管理产生的一系列问题,而且使图书企业提高了管理效率,减少了管理成本,增加了经济效益。通过管理系统对图书企业的发展进行
,可以收集大量关键、可靠的数据。企业决策层分析这些数据,作出合理决策,及时调整,使之能够更好地遵循市场的销售规律,适应市场的变化,从而让企业能够在激烈的行业竞争中占据一席之地。
1.2 需 求 分 析
目前,图书市场日益激烈的竞争迫使图书企业希望采用一种新的管理方式来加快图书流通信息的反馈速度,而计算机信息技术的发展为图书管理注入了新的生机。通过对市场的调查得知,一款合格的图书信息管理系统必须具备以下3个特点:
, 能够对图书信息进行集中管理。
, 能够大大提高用户的工作效率。
, 能够对图书的部分信息进行查询。
1.3 系 统 设 计
1.3.1 系统目标
对于图书管理这样的管理系统,必须要满足使用方便、操作灵活和安全性好等设计需求。设计本系统时应该完成以下几个目标:
, 图书的录入使用交互方式。
, 能够浏览文件中存储的全部图书。
, 图书信息在屏幕上的输出要有固定
。
, 系统最大限度地实现易维护性和易操作性。
, 系统运行稳定、安全可靠。
1.3.2 系统功能结构
系统功能结构如图1.1所示。
2
第1章 图书管理系统,Visual C++ 6.0实现, , 添加新书模块:该模块主要供图书管理者使用。图书管理者应用该模块将图书信息录入到系
统,系统将图书信息保存到文件中。 , 浏览全部模块:该模块供读者和图书管理者使
图书管理程序 图书管理系统 用。图书管理者可以通过该模块查看图书是否
存在,以及获取图书的编号,方便日后删除。
读者可以根据该模块了解到图书的价格和作
者等信息,从而决定是否购买。 浏览 , 删除图书模块:该模块主要供图书管理者使浏览图书 删除 全部 添加全部录入 图书 图书 。图书管理者可以通过该模块删除书店中已用新书模块 模块模块 记录 模块 经销售完的图书的信息。 模块
1.3.3 系统预览 图1.1 系统功能结构 图书管理系统由添加图书、浏览全部和删除图书3部分组成,由于篇幅有限,在此只给出部分功
能预览图。
图书管理系统主界面如图1.2所示。添加新书界面如图1.3所示。
图1.2 图书管理系统主界面 图1.3 添加新书界面 浏览全部界面如图1.4所示。
图1.4 浏览全部界面
3
C++项目开发全程实录
1.4 公共类设计 图书管理系统需要创建CBook类,通过CBook类可实现图书记
录的写入和删除,还可以通过CBook类查看每条图书的信息。CBookCBook
类中包含m_cName、m_cIsbn、m_cPrice和m_cAuthor 4个成员变量,m_cName m_cIsbn 分别代
图书的名称、ISBN编号、价格和作者。在设计类时,可以将m_cPrice m_cAuthor 成员变量看做属性,这样类中还需要有设置属性和获取属性的成员函 GetBookFormFile 数,设置属性的函数以set开头,获取属性的函数以get开头。CBookWriteData DeleteData .5所示。 类设计图如图1GetName SetName CBook类定义在头文件Book.h中,代码如下: GetIsbn SetIsbn „ #define NUM1 128
#define NUM2 50 图1.5 CBook类设计图 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];
};
CBook类成员函数的实现都存储在实现文件Book.cpp内。
#include "Book.h"
#include
#include
4
第1章 图书管理系统,Visual C++ 6.0实现,
#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_cIsbn,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); }
函数WriteData、GetBookFromFile和DeleteData是类对象读写文件的函数,相当于操作数据库的
接口。
(1)成员函数WriteData主要实现将图书对象写入到文件中。
void CBook::WriteData()
{
5
C++项目开发全程实录
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();
}
(2)成员函数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_cIsbn,cIsbn,NUM2);
ifile.read(cAuthor,NUM2);
if(ifile.tellg()>0)
strncpy(m_cAuthor,cAuthor,NUM2);
}
catch(...)
{
throw "file error occurred";
ifile.close();
}
ifile.close();
6
第1章 图书管理系统,Visual C++ 6.0实现, }
(3)成员函数DeleteData负责将图书信息从文件中删除。
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 number 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");
}
7
C++项目开发全程实录
1.5 主窗体模块设计
1.5.1 主窗体模块概述
主程序界面是应用程序提供给用户访问其他功能模块的平台,根据实际需要,图书管理系统的主
界面采用了传统的“数字选择功能”风格。输入数字1进入到添加新书模块,输入数字2进入到浏览
全部模块,输入数字3进入到删除图书模块。图书管理系统主界面如图1.6所示。
图1.6 系统主界面
1.5.2 主窗体模块技术分析
要实现图书管理系统的功能,需要对引用库函数添加头文件引用。头文件引用和宏定义的代码如下:
#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():显示开始菜单。
8
第1章 图书管理系统,Visual C++ 6.0实现, , void WaitView(int iCurPage):浏览数据时等待用户操作。 , void WaitUser():等待用户操作。
, void GuideInput():使用向导添加图书信息。
, int GetSelect():获得用户菜单选择。
, long GetFileLength(ifstream & ifs):获取文件长度。
, void ViewData(int iSelPage):浏览所有图书记录。
, void DeleteBookFromFile():在文件中产生图书信息。
, void mainloop():主循环。
1.5.3 主窗体模块实现过程
图书管理系统的主窗体设计实现过程如下。
(1)在控制台中输入mode命令可以设置控制显示信息的行数、列数和背景颜色等信息。SetScreenGrid
函数主要通过system函数来执行mode命令,CMD_COLS和CMD_LINES是宏定义中的值。
void SetScreenGrid()
{
char sysSetBuf[80];
sprintf(sysSetBuf,"mode con cols=%d lines=%d",CMD_COLS,CMD_LINES);
system(sysSetBuf);
}
(2)SetSysCaption函数主要完成在控制台的标题栏上显示Sample信息。控制台的标题栏信息可
以使用title命令来设置,函数中使用system函数来执行title命令。
void SetSysCaption()
{
system("title Sample");
}
(3)ClearScreen函数主要通过system函数来执行cls命令,完成控制台屏幕信息的清除。
void ClearScreen()
{
system("cls");
}
(4)SetSysCaption函数共有两个版本,这是SetSysCaption函数的另一个版本,主要实现在控制
台的标题栏上显示指定字符。
void SetSysCaption( const char *pText) {
char sysSetBuf[80];
sprintf(sysSetBuf,"title %s",pText);
system(sysSetBuf);
}
9
C++项目开发全程实录
(5)ShowWelcome函数在屏幕上显示“图书管理系统”字样的欢迎信息,“图书管理系统”字
样应尽量显示在屏幕的中央位置。
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;
}
(6)ShowRootMenu函数主要显示系统的主菜单,系统中有3个菜单选项,分别是添加新书、浏
览全部和删除图书。3个菜单选项是进入系统3个模块的入口。
void ShowRootMenu() {
cout << setw(40);
cout << "请选择功能" << endl;
cout << endl;
cout << setw(38);
cout << "1 添加新书" << endl;
cout << endl;
cout << setw(38);
cout << "2 浏览全部" << endl;
cout << endl;
cout << setw(38);
cout << "3 删除图书" << endl; }
(7)WaitUser函数主要负责当程序进入某一模块后,等待用户进行处理。用户可以选择返回主菜
单,也可以直接退出系统。
void WaitUser()
{
int iInputPage=0;
cout << "enter?返回主菜单 q退出" << endl;
char buf[256];
gets(buf);
if(buf[0]=='q')
system("exit"); }
10
第1章 图书管理系统,Visual C++ 6.0实现,
(8)main函数是程序的入口,主要调用了SetScreenGrid、SetSysCaption和mainloop 3个函数,
其中,mainloop函数是主函数,负责模块执行的调度,主要代码如下:
void mainloop()
{
ShowWelcome();
while(1)
{
ClearScreen();
ShowWelcome();
ShowRootMenu();
switch(GetSelect())
{
case 1:
ClearScreen();
GuideInput();
break;
case 2:
ClearScreen();
ViewData();
break;
case 3:
ClearScreen();
DeleteBookFromFile();
break;
}
}
}
(9)GetSelect函数主要负责获取用户在菜单中的选择。
int GetSelect()
{
char buf[256];
gets(buf);
return atoi(buf);
}
其他函数都应用在添加新书模块、浏览全部模块和删除图书模块中,相关内容将在具体模块中讲解。
1.6 添加新书模块设计
1.6.1 添加新书模块概述
在图书管理系统主窗体中输入数字1,则进入到添加新书模块中。添加新书模块中主要需要用户输
入所要添加的图书的书名、ISBN编码、价格以及作者信息,其运行效果如图1.7所示。
11
C++项目开发全程实录
图1.7 添加新书
1.6.2 添加新书模块技术分析
在添加新书模块中定义了GuideInput函数,通过在main函数中调用来完成添加图书的功能。
void GuideInput();
其次,利用CBook类构建一个CBook对象,通过CBook对象的成员函数WriteData将图书信息写
入文件。
CBook book(inName,inIsdn,inPrice,inAuthor);
book.WriteData();
1.6.3 添加新书模块实现过程
图书管理系统中添加新书模块的实现代码如下:
void GuideInput()
{
char inName[NUM1];
char inIsdn[NUM1];
char inPrice[NUM2];
char inAuthor[NUM2];
cout << "输入书名" << endl;
cin >> inName;
cout << "输入ISBN" << endl;
cin >> inIsdn;
cout << "输入价格" << endl;
cin >> inPrice;
cout << "输入作者" << endl;
cin >> inAuthor;
CBook book(inName,inIsdn,inPrice,inAuthor);
book.WriteData();
cout << "Write Finish" << endl;
12
第1章 图书管理系统,Visual C++ 6.0实现,
WaitUser();
}
1.7 浏览全部模块设计
1.7.1 浏览全部模块概述
在图书管理系统主窗体中输入数字2,则进入到浏览全部模块。此模块中可按页数显示图书记录,每页可以显示20条记录。主要实现的功能是显示所有图书的编号、图书名、ISBN编码、价格以及作者信息,记录了当前记录中书的总数量、共有多少页及当前页数,还实现了翻页及返回主菜单的功能。
8所示。 其运行效果如图1.
图1.8 浏览全部
1.7.2 浏览全部模块技术分析
图书管理系统中浏览全部模块主要通过定义函数ViewData来完成。在函数ViewData中直接使用文件流类打开存储图书信息的文件book.dat。
void ViewData(int iSelPage = 1)
再定义一个GetFileLength函数,用来获取文件的长度。函数需要指定一个文件流对象,然后根据文件流的tellg函数计算出文件流绑定的文件长度。计算过程是先通过tellg函数获取文件指针的位置,然后通过seekg函数将文件指针移到文件末尾,再通过tellg函数获取文件指针的位置,此时的文件指针的位置就是文件的长度,最后通过seekg函数将文件指针恢复到原来的位置。
long GetFileLength(ifstream & ifs)
1.7.3 浏览全部模块实现过程
在函数ViewData中直接使用文件流类打开存储图书信息的文件book.dat,然后根据页序号读取文件内
13
C++项目开发全程实录
容,因为每条图书记录的长度相同,这样就很容易计算出每条记录在文件中的位置,然后将文件指针移动
到每页第一条图书记录处,顺序地从文件中读取20条记录,并将信息显示在屏幕上。其代码如下:
void ViewData(int iSelPage = 1)
{
int iPage=0;
int iCurPage=0;
int iDataCount=0;
char inName[NUM1]; //存储图书名称的变量
char inIsbn[NUM1]; //存储图书ISBN编号的变量
char price[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 << setw(5)<<"Index" ;
cout << setw(22) << "Name" << setw(22) << "Isbn" ;
cout << setw(15) << "Price" << setw(15) << "Author";
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(price,0,50);
memset(inAuthor,0,50);
if(bIndex)
cout <> iDelCount;
CBook tmpbook;
tmpbook.DeleteData(iDelCount);
cout << "Delete Finish" << endl;
WaitUser();
}
1.9 项目文件清单 图书管理系统文件清单如表1.1所示。
16
第1章 图书管理系统,Visual C++ 6.0实现,
表1.1 图书管理系统设计清单
文 件 名 文 件 类 型 说 明
源文件 实现图书记录的写入和删除 Book.cpp
数据文件 存放图书对象 book.dat
源文件 主窗体设计 Main.cpp
工程文件 工程文件 Sample.dsw
头文件 定义图书类 Book.h
1.10 本 章 总 结
至此,一个简单的图书管理系统就完成了,本系统的开发过程符合软件工程方面的要求,但由于
篇幅的关系,系统设计得比较小,没有应用模型,读者可以使用一些模型技术来不断完善该系统。
17