c++学习笔记(图书馆易简系统)

时间:2022-08-05 17:51:22

前言:该文章主要是学习与练习C++代码之用,涉及类、宏、控制语句等基础语法。主要实现用户注册,用户登入,图书馆增加图书,图书查询,数据库本地存储功能。PS:就是练习代码而已~

#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
#include <map>
#include <stdlib.h>
#include <sstream>
#include <Shlwapi.h>
#include <fstream>
#pragma comment(lib,"Shlwapi.lib")
using namespace std;

//枚举系统状态
enum LV
{
INFO,
ERR,
OK
};

#define FG_RED FOREGROUND_INTENSITY | FOREGROUND_RED
#define FG_GREEN FOREGROUND_INTENSITY | FOREGROUND_GREEN
#define FG_GRAY FOREGROUND_INTENSITY | FOREGROUND_BLUE

//宏 (代码内字符串的替换)
#define LERR LOGLEVEL(ERR)
#define LOK LOGLEVEL(OK)
#define LINFOR LOGLEVEL(INFOR)

//枚举图书状态
enum STATUS
{
IN_STOCK,
ON_LOAN
};
class Book
{
public:
Book(int inputID, string inputName,STATUS inputStatus=IN_STOCK)
{
id = inputID;
name = inputName;
status = inputStatus;
}

//给数装配一些属性
int id;
string name;
STATUS status;


};


//log 抽象为一个类
class LOGLEVEL
{
public:
//构造函数(造房子)
//成员变量
LV m_lv;
HANDLE m_handle;
LOGLEVEL(LV lv)
{
m_lv = lv;

//Windows API 获取标准输出句柄
m_handle=GetStdHandle(STD_OUTPUT_HANDLE);

if (lv == ERR)
{
SetConsoleTextAttribute(m_handle,FG_RED);
}
else if(lv=OK)
{
SetConsoleTextAttribute(m_handle,FG_GREEN);
}
else
{
SetConsoleTextAttribute(m_handle, FG_GRAY);
}
}
//析构函数(拆房子)
~LOGLEVEL()
{
// 将控制台返程灰色字体
SetConsoleTextAttribute(m_handle, FG_GRAY);
}
//操作符重载
operator char*()
{
return "";
}
};

typedef vector<string> STR_ARR;

vector<string> split(string sourceStr)
{
//随便缓冲
string chunkBuffer = "";
vector<string> totalChunks;
//c++ 11 对于每一个sourceStr当中的字符,遍历之
for each (char c in sourceStr)
{


//判断是否是空格
//char字符用单引号判断
if (c == ' ')
{
//把当前的碎片缓冲存起来
totalChunks.push_back(chunkBuffer);
//清空缓存碎片
chunkBuffer = "";
}
//不是空格
else
{
chunkBuffer += c;
}


}

//收尾
if (chunkBuffer != "")
{
//把当前的碎片缓冲存起来
totalChunks.push_back(chunkBuffer);
//清空缓存碎片
chunkBuffer = "";
}
return totalChunks;
}

//类似字典的数据结构(映射)用作数据库


//class 类

class BookSystem
{
public:
BookSystem()
{
lastID = 0;
}
//路径假设为c:\123.txt
string getDbPath()
{
//获取自己的路径
char buff[MAX_PATH];
GetModuleFileName(NULL, buff, MAX_PATH);

//获取自己的文件夹
PathRemoveFileSpec(buff);
//链接数据库文件名
PathAppend(buff, "booksSysDb.txt");
return buff;
}

//抽象动作
void runCommand(string input)
{
//分隔输入
STR_ARR chunks = split(input);

//判断命令
string commandName = chunks[0];
if (commandName == "reg")
{
reg(chunks);
}
else if (commandName == "login")
{
login(chunks);
}
else if (commandName == "addbook")
{
addbook(chunks);
}
else if (commandName == "listbook")
{
listbook(chunks);
}
else if (commandName == "savedb")
{
savedb(chunks);
}
else if (commandName == "loaddb")
{
loaddb(chunks);
}
else
{
cout << "你输出错了,亲爱的" << endl;
}
}
void reg(STR_ARR chunks)
{

string userName = chunks[1];
string password = chunks[2];

//检查用户名是否存在
if (userDataBase.find(userName)==userDataBase.end())
{
//没找到用户
//写入数据库
userDataBase[userName] = password;
cout <<LOK<< "reg is successed" << endl;
}
else
{
cout <<LERR<< "the user" << userName << "has been regged" << endl;
}



return;
}

void login(STR_ARR chunks)
{
string userName = chunks[1];
string password = chunks[2];
//判断用户名和密码是否匹配
//从头找到尾,依然没发现的话
if (userDataBase.find(userName) == userDataBase.end())
{
cout << LERR << "The user" << userName << "is not find" << endl;
}
else
//存在用户
{
if (userDataBase[userName] == password)
{
//如果一致
cout << LOK << "The user" << userName << "logged in successfully" << endl;
}
else
{
cout << LERR << "Password is not correct" << endl;
}
}
}
//映射用作数据库
map<string, string> userDataBase;

//书籍数据库
vector<Book> bookDB;

int lastID;

//添加书命令
void addbook(STR_ARR chunks)
{
//添加书
string name = chunks[1];
string countStr = chunks[2];
//字符串转换成数字
int d;
stringstream ss(countStr);
ss>>d;
//sscanf(countStr, "%d", &d);
for (int i=0;i<d;i++)
{
lastID++;
Book newBook(lastID, name);
bookDB.push_back(newBook);
}
cout << LOK << "ADDBOOK IS DONE"<<endl;
}

void listbook(STR_ARR chunks)
{
for each(Book book in bookDB)
{
cout << LOK << book.id << " " << book.name << endl;
}
}
void loaddb(STR_ARR chunks)
{

}
void loaddb_internal()
{
//加载数据

//获取当前路径
string dbPath = getDbPath();
//创建DB输入文件
ifstream input(dbPath);

//读取文本每一行,直到结束
while (!input.eof())
{
string currLine;
getline(input, currLine);
//切割
auto chunks = split(currLine);

//判断内容是否为空白
if (chunks.size() == 0)
{
//跳出循环
break;
}
//如果有内容
if (chunks[0] == "USER")
{
string userName = chunks[1];
string password = chunks[2];

//插入DB
userDataBase[userName] = password;

}
else if (chunks[0]=="Book")
{
string idstr = chunks[1];
string name = chunks[2];
string statusStr = chunks[3];
//转换idstr为整数
int id;
istringstream(idstr)>>id;
//enum类型本身是int,我们需要用的时候强制转化
STATUS status;
istringstream(statusStr) >> (int&)status;
Book currBook(id,name,status);
bookDB.push_back(currBook);

}
}
}
void savedb(STR_ARR chunks)
{
//获取当前路径
string dbPath = getDbPath();

//文件输出流
//output file stream c++ ofstream
ofstream output(dbPath);

//保存用户信息
for each(auto keyValue in userDataBase)
{
//输出USER
output << "USER" <<" "<<keyValue.first<<" " << keyValue.second << endl;

}

for each(auto book in bookDB)
{
output << "Book" << " " << book.id << " " << book.name << " " << book.status << endl;
}
cout << "save successfully" << endl;
output.close();
}

};



int main(int argc, char* argv[])
{

//我们在外面声明了BookSystem,现在我们对类进行实体化
BookSystem bookSys;
bookSys.loaddb_internal();
cout << LOK<<("*****************") << endl;
cout << LOK<<("图书管理系统C++语言练习") << endl;
cout << LOK<<("*****************") << endl;



//输入缓冲
//STL 内建 Standart Template Library 标准库
string inputBuffer;

do {
//打印提示符
cout << ("BOOKSYS>");
//接受输入,cin碰到空格就会砍掉输入
//cin >> inputBuffer;
getline(cin,inputBuffer);
bookSys.runCommand(inputBuffer);

} while (inputBuffer != "exit");
return 0;
}

c++学习笔记(图书馆易简系统)


(参考<c++从0基础学习到实践>)