逆向软件设计与开发
一、来源
来自于同学大一的作业 图书管理系统
二、运行环境+运行结果的截图(伸缩代码附上)
1.使用c语言编写
2.处理器 Intel(R) Core(TM) Ultra 7 155H 3.80 GHz
版本 Windows 11
3.运行截图



点击查看代码
#include<string>
#include<fstream>
#include "buyer.h"
#include "member.h"
#include "honoured_guest.h"
#include "layfolk.h"
#include "book.h"
#include "order.h"
void readbook(){
ifstream ifs;
ifs.open("BOOK.txt",ios::in);
if(!ifs.is_open())
cout<<"文件打开失败"<<endl;
char buf[100]={0};
while(ifs.getline(buf,sizeof(buf)))
{cout<<buf<<endl;}
ifs.close();
return;
}
void writebook()
{
ofstream ofs;
ofs.open("Book.txt",ios::app);
cout<<"请输入需要增加的书籍数量"<<"\n";
int x;
cin>>x;
for(int i=0;i<x;i++){
cout<<"请按以下顺序输入书籍信息"<<endl;
cout<<"1.书号"<<"\n";
cout<<"2.书名"<<"\n";
cout<<"3.作者"<<"\n";
cout<<"4.出版社"<<"\n";
cout<<"5.价格"<<"\n";
string book_ID; //书号
string book_name; //书名
string author; //作者
string publishing; //出版社
double price;//价格
cin>>book_ID>>book_name>>author>>publishing>>price;
ofs<<"书号:"<<book_ID<<"\t";
ofs<<"书名:"<<book_name<<"\t";
ofs<<"作者:"<<author<<"\t";
ofs<<"出版社:"<<publishing<<"\t";
ofs<<"价格:"<<price<<"\n";}
/*ofs<<ofs<<"书号:7-302-04504-6"<<"\t";
ofs<<"书名:C++程序设计"<<"\t";
ofs<<"作者:谭浩强"<<"\t";
ofs<<"出版社:清华"<<"\t";
ofs<<"价格:25"<<"\n";
ofs<<ofs<<"书号:7-402-03388-9"<<"\t";
ofs<<"书名:数据结构"<<"\t";
ofs<<"作者:许卓群"<<"\t";
ofs<<"出版社:北大"<<"\t";
ofs<<"价格:20"<<"\n";*/
ofs.close();
return;
}
void readcust(){
ifstream ifs;
ifs.open("cust.txt",ios::in);
if(!ifs.is_open())
cout<<"文件打开失败"<<endl;
char buf[1024]={0};
while(ifs>>buf)
{cout<<buf<<endl;}
ifs.close();
return;
}
void writecust()
{
cout<<"请按以下顺序输入顾客信息"<<endl;
cout<<"1.姓名"<<"\t";
cout<<"2.购书人编号"<<"\t";
cout<<"3.地址"<<"\t";
cout<<"4.购书人身份(请输入普通用户/贵宾/x级会员)"<<"\n";
string name;//姓名
int buyerID;//购书人编号
string address;//地址
string buyeract;//购书人身份
cin>>name>>buyerID>>address>>buyeract;
ofstream ofs;
ofs.open("cust.txt",ios::app);
ofs<<"姓名:"<<name<<" ";
ofs<<"购书人编号:"<<buyerID<<" ";
ofs<<"地址:"<<address<<" ";
ofs<<"购书人身份:"<<buyeract<<"\n";
ofs<<"姓名:林小茶"<<" ";
ofs<<"购书人编号:1"<<" ";
ofs<<"地址:北京"<<" ";
ofs<<"购书人身份:普通用户"<<"\n";
ofs<<"姓名:王遥遥"<<" ";
ofs<<"购书人编号:2"<<" ";
ofs<<"地址:上海"<<" ";
ofs<<"购书人身份:贵宾"<<"\n";
ofs<<"姓名:赵红艳"<<" ";
ofs<<"购书人编号:3"<<" ";
ofs<<"地址:广州"<<" ";
ofs<<"购书人身份:5级会员"<<"\n";
ofs.close();
return;
}
void readorder(){
ifstream ifs;
ifs.open("order.txt",ios::in);
if(!ifs.is_open())
cout<<"文件打开失败"<<endl;
char buf[1024]={0};
while(ifs>>buf)
{cout<<buf<<endl;}
ifs.close();
return;
}
void writeorder(buyer* a,book* b)
{
string a1=a->getbuyname();
string a2=b->getbook_name();
double a3=b->getprice();
order B(a1,a2,a3);
ofstream ofs;
ofs.open("order.txt",ios::app);
ofs<<"订单编号:"<<B.getordercount()<<"\t";
ofs<<"购书人姓名"<<B.getbn()<<"\t";
ofs<<"书名:"<<B.getbm()<<"\t";
ofs<<"价格:"<<B.getmo()<<"\n";
ofs.close();
return;
}
int buybook(){
cout<<"请选择购书数量"<<"\n";
int x;
cin>>x;
return x;
}
book listbook(){
cout<<"请按以下顺序输入书籍信息"<<endl;
cout<<"1.书号"<<"\n";
cout<<"2.书名"<<"\n";
cout<<"3.作者"<<"\n";
cout<<"4.出版社"<<"\n";
cout<<"5.价格"<<"\n";
string book_ID; //书号
string book_name; //书名
string author; //作者
string publishing; //出版社
double price;
cin>>book_ID>>book_name>>author>>publishing>>price;
book b1(book_ID,book_ID,author,publishing,price);
return b1;
}
void log(){
for(;;){
cout<<"请输入购书人信息"<<endl;
cout<<"请按以下顺序输入顾客信息"<<endl;
cout<<"1.姓名"<<"\n";
cout<<"2.购书人编号"<<"\n";
cout<<"3.地址"<<"\n";
cout<<"4.购书人身份(普通用户输入1;会员用户输入2;贵宾用户输入3"<<"\n";
string name;//姓名
int buyerID;//购书人编号
string address;//地址
int num;
int sum=0;
cin>>name>>buyerID>>address>>num;
int count;
if(num==1){
count=buybook();
layfolk s1(name,buyerID,address,0);
for(int i=0;i<count;i++){
book B=listbook();
writeorder(&s1,&B);
sum+=B.getprice();
}
s1.display ();
s1.setpay(sum);
cout<<"此次购书费用为"<<s1.getpay()<<"\n";
return;
}
else if(num==2){
cout<<"请输入您的会员级别"<<"\n";
int b;
for(;;) {
cin>>b;
if(b>5){
cout<<"输入有误,请重新输入\n";}
else
{
member s2(name,buyerID,b,address,0);
count=buybook();
for(int i=0;i<count;i++){
book B=listbook();
writeorder(&s2,&B);
sum+=B.getprice();
}
s2.display();
s2.setpay(sum);
cout<<"此次购书费用为"<<s2.getpay()<<"\n";
return;}
}
}
else if(num==3){
cout<<"尊敬的贵宾用户,欢迎您!\n";
cout<<"请输入您的专有折扣"<<"\n";
int b;
cin>>b;
honoured_guest s3(name,buyerID,b,address,0);
count=buybook();
for(int i=0;i<count;i++){
book B=listbook();
writeorder(&s3,&B);
sum+=B.getprice();
}
s3.display();
s3.setpay(sum);
cout<<"此次购书费用为"<<s3.getpay()<<"\n";
return;
}
else
cout<<"输入错误!\n"<<"请根据提示重新输入!"<<"\n";
}
}
void out(){
cout<<"欢迎下次光临!"<<endl;
}
void menu(){
cout<<"********************************"<<"\n";
cout<<"******欢迎使用网上购书系统******"<<"\n";
cout<<"******** 请选择以下服务*********"<<"\n";
cout<<"**********0.图书信息总览********"<<"\n";
cout<<"**********1.增加书籍信息********"<<"\n";
cout<<"**********2.顾客信息总览********"<<"\n";
cout<<"**********3.增加顾客信息********"<<"\n";
cout<<"**********4.网上购书************"<<"\n";
cout<<"**********5.查看订单信息********"<<"\n";
cout<<"**********6.退出系统************"<<"\n";
cout<<"********************************"<<"\n";
}
void show() {
int n;
while (1) {
menu();
cin >> n;
switch (n) {
{
case 0:
readbook();
break;
case 1:
writebook();
break;
case 2:
readcust();
break;
case 3:
writecust();
break;
case 4:
log();
break;
case 5:
readorder();
break;
case 6:
out();
return;
default:
cout<<"请重新输入"<<endl;
}
}
}
}
int main(){
show();
return 0;
}
三、主要问题列表,针对问题要了改善或者重构
1.重构购书逻辑。原代码中 log() 函数逻辑复杂且冗长,难以维护
2.原代码中写入文件时没有对用户输入进行校验,可能导致非法数据写入。
3.原代码中折扣逻辑分散在各个子类中,难以维护。
四、新代码附上(只要你自己改进的地方)
点击查看代码
void log() {
cout << "请输入购书人信息(姓名 编号 地址 身份):" << endl;
string name, address, buyeract;
int buyerID;
cin >> name >> buyerID >> address >> buyeract;
cin.ignore();
buyer* customer = nullptr;
if (buyeract == "普通用户") {
customer = new layfolk(name, buyerID, address, 0);
} else if (buyeract == "会员") {
int grade;
cout << "请输入会员级别(1-5):";
cin >> grade;
customer = new member(name, buyerID, grade, address, 0);
} else if (buyeract == "贵宾") {
double discount;
cout << "请输入贵宾折扣(0-10):";
cin >> discount;
customer = new honoured_guest(name, buyerID, discount, address, 0);
} else {
cout << "输入错误!" << endl;
return;
}
int count = buybook();
double sum = 0;
for (int i = 0; i < count; i++) {
book B = listbook();
writeorder(customer, &B);
sum += B.getprice();
}
customer->setpay(sum);
customer->display();
cout << "此次购书费用为:" << customer->getpay() << endl;
delete customer;
}
点击查看代码
void writebook() {
ofstream ofs("BOOK.txt", ios::app);
if (!ofs.is_open()) {
cout << "文件打开失败" << endl;
return;
}
cout << "请输入需要增加的书籍数量: ";
int x;
cin >> x;
cin.ignore(); // 清除缓冲区
for (int i = 0; i < x; i++) {
cout << "请按以下顺序输入书籍信息(书号 书名 作者 出版社 价格):" << endl;
string book_ID, book_name, author, publishing;
double price;
getline(cin, book_ID);
getline(cin, book_name);
getline(cin, author);
getline(cin, publishing);
cin >> price;
cin.ignore();
ofs << "书号:" << book_ID << "\t";
ofs << "书名:" << book_name << "\t";
ofs << "作者:" << author << "\t";
ofs << "出版社:" << publishing << "\t";
ofs << "价格:" << price << "\n";
}
ofs.close();
}
点击查看代码
void buyer::setpay(double p) {
if (dynamic_cast<honoured_guest*>(this)) {
p *= (10 - ((honoured_guest*)this)->discount_rate) / 10.0;
} else if (dynamic_cast<member*>(this)) {
int grade = ((member*)this)->leaguer_grade;
switch (grade) {
case 1: p *= 0.95; break;
case 2: p *= 0.90; break;
case 3: p *= 0.85; break;
case 4: p *= 0.80; break;
case 5: p *= 0.70; break;
}
}
pay += p;
}

六、总结:难点、花时间比较久的、逆向软件工程的一些思考
1.难点:
代码可读性差:
1.缺少注释,难以理解函数和逻辑的作用
2.变量命名不规范,例如 ifs、ofs、a1、a2 等,难以直接理解其含义
3.逻辑复杂且冗长,尤其是在 log() 函数中,嵌套逻辑过多,难以维护。
4.该软件初始交互页面较为美观,因此更多需要修改 改进的是代码的逻辑,这点比较花费时间,理解,并且思考出改进方法是该作业的难点之一。
2.思考
逆向工程不仅仅是修复代码,更重要的是重构代码,使其更易于维护和扩展。重构过程中,我将复杂的逻辑拆分为多个小函数,增加了注释,并优化了变量命名,显著提高了代码的可读性和可维护性。在逆向工程中,良好的文档和注释是理解代码的关键。重构过程中,我增加了详细的注释,解释每个函数和关键逻辑的作用。这不仅有助于当前的开发,也为后续的维护提供了便利。

浙公网安备 33010602011771号