c++実戦(二)図書管理システム
この実戦を通じて,ソフトウェア全体の設計,クラスの応用,ファイルにデータを格納する方法などを理解する.
このプログラムは、図書の入力、削除、およびすべての図書記録を閲覧する3つのモジュールを完了します.
1.図書類を設計する
2.メインプログラム、主にインタフェースを設計する
3.図書の追加
4.図書を閲覧する
5.図書の削除
このプログラムは、図書の入力、削除、およびすべての図書記録を閲覧する3つのモジュールを完了します.
1.図書類を設計する
#include "stdafx.h"
#include "Book.h"
#include "string"
#include "fstream"
#include "iostream"
#include "iomanip"
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::GetPrice() {
return m_cPrice;
}
void CBook::SetPrice(char* cPirce) {
strncpy(m_cPrice, cPirce, NUM2);
}
char* CBook::GetAuthor() {
return m_cAuthor;
}
void CBook::SetAuthor(char* cAuthor) {
strncpy(m_cAuthor, cAuthor, NUM2);
}
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();
}
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, NUM2);
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 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::app | ios::out);
tmpfile.open("temp.dat", ios::binary | ios::in | ios::out | ios::trunc);
// ios::trunc ,
file.seekg(0, ios::end);
respos = file.tellg();
// , ,
// ,
iDataCount = respos / (NUM1 + NUM1 + NUM2 + NUM2);
// NUM1 + NUM1 + NUM2 + NUM2
// /
if (iCount < 0 || iCount > iDataCount)
{
throw "Input number error";
}
else
{
// file.seekg((iCount-1)*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
//
file.seekg(0, ios::beg);
for (int j = 1; j <= iDataCount; j++)
{
if (j == iCount)
{
file.seekg((iCount)*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
}
if (!file.eof())
{
memset(cTempBuf, 0, NUM1 + NUM1 + NUM2 + NUM2);
// NUM1 + NUM1 + NUM2 + NUM2 0 cTempBuf
file.read(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);
// file NUM1 + NUM1 + NUM2 + NUM2
// cTempBuf 。
tmpfile.write(cTempBuf, NUM1 + NUM1 + NUM2 + NUM2);
// cTempBuf tmpfile
}
}
file.close();
tmpfile.seekg(0, ios::beg);
// tmpfile
ofile.open("book.dat");
// "book.dat" , ofile ,
// ofile.seekp((iCount - 1)*(NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
ofile.seekp(0, ios::beg);
// seekp:
for (int i = 1; i <= iDataCount; i++)
{
if (!ofile.eof())
{
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");
}
2.メインプログラム、主にインタフェースを設計する
// simATM.cpp : 。
//
#include "stdafx.h"
#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 Show Welcome: 。
void ShowRootMenu: 。
void WaitView(int iCurPage): 。
void WaitUser: 。
void Guidelnput: 。
int GetSelect: 。
long GetFileLength(ifstream & ifs): 。
void ViewData(int iSelPage): 。
voidDeleteBookFromFile: 。
void mainloop: 。
*/
void SetScreenGrid();
void ClearScreen();
void SetSysCaption();
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 SetScreenGrid()
/*
mode 、 。
SetScreenGrid system mode ,
CMD_COLS CMD_LINES 。
*/
{
char sysSetBuf[80];
sprintf(sysSetBuf, "mode con cols=%d lines=%d", CMD_COLS, CMD_LINES);
system(sysSetBuf);
}
void SetSysCaption()
/*
SetSysCaption Sample 。
title ,
system title 。
*/
{
system("title Sample");
}
void ClearScreen()
/*
ClearScreen system cls ,
。
*/
{
system("cls");
// system("cls") #include ,
//
}
void SetSysCaption(const char *pText)
/*
SetSysCaption , SetSysCaption ,
*/
{
char sysSetBuf[80];
sprintf(sysSetBuf, "title %s", pText);
system(sysSetBuf);
}
void ShowWelcome()
/*
ShowWelcome “ ” ,
“ ” 。
*/
{
for (int i = 0; i<7; i++)
{
cout << endl;
}
cout << setw(50);
cout << "*********************" << endl;
cout << setw(50);
cout << "* *" << endl;
cout << setw(50);
cout << "*********************" << endl;
// std::setw(n) , iomanip (#include )
// setw(int n) (< ,
// atoi() (int), int atoi(const char* str);
// atoi() str , ( ,tab , isspace() ),
// , ('\0') ,
// ; str int str , 0。
}
void WaitUser()
/*
WaitUser , 。
, 。
*/
{
int iInputPage = 0;
cout << "enter ,q " << endl;
char buf[256];
gets_s(buf);
if (buf[0] == 'q')
system("exit");
}
void WaitView(int iCurPage)
{
char buf[256];
cin >> buf;
if (buf[0] == 'q')
system("exit");
if (buf[0] == 'm')
mainloop();
if (buf[0] == 'n')
ViewData(iCurPage);
}
long GetFileLength(ifstream& ifs)
/*
GetFileLength , 。
:1. ifstream ( );
2. seekg get pointer ,seekg(0, ios_base::end);
3. tellg , get pointer ;
4. get pointer, , , seekg(0, ios_base::beg)。
*/
{
long tmppos;
long respos;
tmppos = ifs.tellg();
// tellg() ,
ifs.seekg(0, ios::end);
// , 0, 。
// seekg() , : , 。
// , , , 。
// :
// ios::beg: , ;
// ios::cur: ;
// ios::end: , 。
// ifstream, istream, get pointer , 。
respos = ifs.tellg();
// , ifs.tellg() ,
// tellg , get pointer
ifs.seekg(tmppos, ios::beg);
// , tmppos,
return respos;
}
void mainloop()
/*
main , SetScreenGrid、SetSysCaption mainloop3 ,
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;
default:
break; // GetSelect() 1、2、3 , while 。
}
}
}
//
void main()
{
SetScreenGrid();
SetSysCaption(" ");
mainloop();
}
3.図書の追加
void GuideInput()
/*
GuideInput ,
、ISBN 、 ,
CBook CBook ,
CBook WriteData 。
*/
{
char inName[NUM1];
char inlsdn[NUM1];
char inPrice[NUM2];
char inAuthor[NUM2];
cout << " :" << endl;
cin >> inName;
cout << " ISBN:" << endl;
cin >> inlsdn;
cout << " :" << endl;
cin >> inPrice;
cout << " :" << endl;
cin >> inAuthor;
// :cin ,TAB , ,
CBook book(inName, inlsdn, inPrice, inAuthor); // CBook ,
book.WriteData();
cout << "Write Finish!" << endl;
//
cout << endl;
cout << "******************************" << endl;
cout << " ( : ,q : ):" << endl;
char buf;
cin >> buf;
if (buf == 'q')
system("exit");
else
GuideInput();
}
4.図書を閲覧する
void ViewData(int iSelPage)
/*
ViewData 。 ViewData ,
20 。 ViewData book.dat,
, ,
, ,
20 , 。
*/
{
int iPage = 0; // iPage
int iCurPage = 0; // iCurPage
int iDataCount = 0; // iDataCount
char inName[NUM1];
char inlsbn[NUM1];
char inPrice[NUM2];
char inAuthor[NUM2];
bool bIndex = false;
int iFileLength;
iCurPage = iSelPage;
ifstream ifile;
// ,ifstream #include
ifile.open("book.dat", ios::binary);
// "book.dat" , ifstream 。
// ( ) C , C++ ,
// string , C 。
// open , ,
// ios::binary, , :
// ios::in
// ios::out
// ios::app
// ios::binary
// ios::nocreate , , 。
// ios::noreplace , ,
// ios::trunc ,
// ios::ate ,
// : ; , ;
// , | ( ); byte 0 ,( )。
iFileLength = GetFileLength(ifile); // ,
iDataCount = iFileLength / (NUM1 + NUM1 + NUM2 + NUM2); // ,
if (iDataCount >= 1)
bIndex = true;
iPage = iDataCount / 20 + 1;
ClearScreen(); //
cout << setw(15) << " :" << iDataCount << " ";
cout << setw(15) << " :" << iPage << " ";
cout << setw(15) << " :" << iCurPage << " ";
cout << setw(25) << "n m " << endl;
cout << std::left << setw(15) << "lndex";
cout << std::left << setw(15) << "Name" << std::left << setw(15) << "Isbn";
cout << std::left << setw(15) << "Price" << std::left << setw(15) << "Author";
cout << endl;
//
try
{
//
ifile.seekg((iCurPage - 1) * 20 * (NUM1 + NUM1 + NUM2 + NUM2), ios::beg);
// IO ,
// IO :
// ifile.eof(): ifile eofbit , true;
// ifile.fail(): ifile failbit badbit , true;
// ifile.bad(): ifile badbit , true;
// ifile.good(): ifile , true;
// good true, bad、fail eof
// true。 , badbit ,fail true。
// , good fail ,
// : !ifile.fail() 。
if (!ifile.fail())
{
for (int i = 1; i < 21; i++) // 20 , 20
{
// , 0
// memset , 。
// :void* memset(void *_Dst, int _Val, size_t _Size)
// _Dst ,_Val ,_Size 。
// ,char inName[128], memset inName “0000...0000(128 0)”,
// :memset(inName, 0, sizeof(char) *128);
// ,memset 。
memset(inName, 0, sizeof(char) * 128);
memset(inlsbn, 0, sizeof(char) * 128);
memset(inPrice, 0, sizeof(char) * 50);
memset(inAuthor, 0, sizeof(char) * 50);
if (ifile.eof()) // , bIndex false
{
bIndex = false;
}
else
bIndex = true;
if (bIndex)
cout << std::right << setw(3) << ((iCurPage - 1) * 20 + i);
// read write
// read : .read(char *buf,int len);
// write : .write(const char *buf, int len);
// , ,
// 。
// , 。
ifile.read(inName, NUM1); //
cout << setw(18) << inName;
ifile.read(inlsbn, NUM1); // ISBN
cout << setw(18) << inlsbn;
ifile.read(inPrice, NUM2);
cout << setw(10) << inPrice;
ifile.read(inAuthor, NUM2);
cout << setw(15) << inAuthor;
cout << endl;
}
}
}
catch (...)
{
cout << "throw file exception" << endl;
throw "file error occurred";
ifile.close();
}
if (iCurPage < iPage)
{
iCurPage = iCurPage + 1;
WaitView(iCurPage); //
}
else
{
WaitView(iCurPage);
}
ifile.close();
}
5.図書の削除
void DeleteBookFromFile()
/*
DeleteBookFromFile ,
DeleteBookFromFile CBook DeleteData 。
DeleteData ,
。
*/
{
int iDelCount;
cout << "Input delete index" << endl;
cin >> iDelCount;
CBook tmpbook;
tmpbook.DeleteData(iDelCount);
cout << "Delete Finish" << endl;
WaitUser();
}