C++课程设计:电梯控制系统程序设计

该文详细介绍了使用C++编程实现的电梯控制系统,包括程序设计背景、类结构图、程序解析及运行展示。程序设计中涉及用户交互、楼层合法性检查、电梯运行模拟等功能,还展示了如何使用VisualStudio创建UML类图。此外,文章还提供了程序的执行流程和总结,强调了面向对象的设计思想和软件调试过程。
摘要由CSDN通过智能技术生成

目录

 

电梯控制系统程序设计背景

类结构图

程序设计

程序释义

运行展示

总结与体会


 

电梯控制系统程序设计背景

电梯控制系统程序设计旨在通过C++编程实现电梯的模拟功能,使用户能够选择上行或下行,并输入要进入的楼层,程序将模拟电梯运行过程并显示经过的每一楼层层数。同时,要求电梯的输入和运行有一定的限制条件,并且在显示楼层时具有一定的延迟效果,以及能在开始运行时显示当前日期。

基本功能要求:

  1. 提供用户界面,让用户选择上行或下行操作,并输入要进入的楼层。
  2. 对用户输入的楼层号进行合法性检查,确保上行时输入的楼层号不小于当前楼层,下行时输入的楼层号不大于当前楼层。
  3. 模拟电梯的运行过程,显示经过的每一楼层层数,并在最终停靠的楼层的输出形式上加以突出显示。
  4. 在电梯开始运行时,显示当前日期。
  5. 程序运行直到用户关闭窗口,即电梯一旦开始运作就会持续运行。

类结构图

有专门的软件去制作UML图,这里我们就采用Vistual Studio来得到UML图。

8adf6d6e38964ac3afd61c947eb2228b.png

 可通过搜索框搜索Vistual Studio Installer,另外一种通过VS里面的顶部导航栏:工具——>获取工具和能力打开。

120dd67311cf4877a6e91a3637a9ca51.png

勾选并下载,VS会重启,完成后再次打开。

在单个组件中搜索"类设计器"

cb1c3a7f415b4aee8c5686120f2c91de.png

再次修改即可,然后就能使用VS来得到UML图了。

右键点击解决方案资源管理器,点击查看,查看类图。

84bacfe88c104320b91d95ba4e21c763.png

 

 

7664ac5cd0b1433a8e292082914f502a.png

程序设计

#include <iostream>
#include <fstream>
#include <vector>
#include <chrono>
#include <thread>
#include <ctime>
using namespace std;

class ELEVATOR {
private:
    int now_floor_e;
    int now_floor_p;
    int want_floor;

    bool choice;             //上下行
    std::vector<int> floor_history; // 记录经过的楼层

public:
    int all_floor;
    ELEVATOR() {
        now_floor_e = 1;   //表示电梯当前所在的楼层
        now_floor_p = 1;   //表示乘客在电梯内的当前楼层
        want_floor = 1;    //表示乘客想要去的楼层
        all_floor = 10; 
        choice = true;     
    }

    int start() {
        displayDate();                                //首先显示当前日期和时间

        bool continueFlag = true;
        while (continueFlag) {
            ask();
            arriave_now_floor_p();
            get_choice();
            get_floor();
            arriave_want_floor();

            cout << "是否继续进行?(输入3退出,否则继续):";   //非3即为继续
            int choice;
            cin >> choice;
            if (choice == 3) {
                continueFlag = false;
            }
        }

        saveFloorHistory();

        return 0;
    }

    void ask() {
        cout << "目前最高层为" << all_floor << "层,欢迎使用!!" << endl;
        cout << "请输入您当前所在的楼层:";
        cin >> now_floor_p;
    }

    void arriave_now_floor_p() {
        cout << "电梯从 " << now_floor_e << " 层到达 " << now_floor_p << " 层" << endl;
        now_floor_e = now_floor_p;
    }

    bool get_choice() {
        cout << "请选择上行(1)或下行(0):";
        cin >> choice;
        return choice;
    }

    void get_floor() {
        cout << "请输入您要前往的楼层:";
        cin >> want_floor;

        while (judge() == -1) {
            cout << "输入不合法!请重新输入:" << endl;
            cin >> want_floor;
        }
    }

    int judge() {
        if (choice && want_floor < now_floor_e) {
            cout << "不合法!目标楼层不能比当前楼层小。" << endl;
            return -1;
        }
        else if (!choice && want_floor > now_floor_e) {
            cout << "不合法!目标楼层不能比当前楼层大。" << endl;
            return -1;
        }

        return 0;
    }

    void arriave_want_floor() {
        cout << "电梯开始运行..." << endl;

        if (choice) {
            for (int floor = now_floor_e; floor <= want_floor; floor++) {
                now_floor_e = floor;
                displayFloor();
                this_thread::sleep_for(chrono::milliseconds(500));
                floor_history.push_back(floor);
            }
        }
        else {
            for (int floor = now_floor_e; floor >= want_floor; floor--) {
                now_floor_e = floor;
                displayFloor();
                this_thread::sleep_for(chrono::milliseconds(500));
                floor_history.push_back(floor);
            }
        }

        cout << "电梯到达目标楼层:" << now_floor_e << " 层" << endl;
    }

    void displayFloor() {
        cout << "电梯经过 " << now_floor_e << " 层" << endl;
    }

    void displayDate() {
        time_t now = time(0);
        tm localTime;
        localtime_s(&localTime, &now);
        char buffer[80];
        strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &localTime);
        cout << "当前日期和时间:" << buffer << endl;
    }
        void saveFloorHistory() {
        std::ofstream file("floor_history.txt");
        if (file.is_open()) {
            time_t now = time(0);
            tm localTime;
            localtime_s(&localTime, &now);
            char buffer[80];
            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &localTime);

            file << "[" << buffer << "] (起始时间)\n";

            for (int floor : floor_history) {
                file << floor << "\n";
            }

            file.close();
            cout << "楼层历史记录已保存到文件。" << endl;
        }
        else {
            cout << "无法打开文件来保存楼层历史记录。" << endl;
        }
    }
};


class ExpressElevator : public ELEVATOR {
public:
    ExpressElevator() {
        all_floor = 20; // 设置更高的最高层数
    }

};

int main() {
    ELEVATOR elevator;
    elevator.start();

    ExpressElevator expressElevator;
    expressElevator.start();

    return 0;
}

程序释义

程序设计实现了一个简单的电梯系统。代码包含了一个名为 ELEVATOR 的类和一个继承自 ELEVATOR 的类 ExpressElevator

ELEVATOR 类的私有成员变量包括:

  • now_floor_e:电梯当前所在的楼层。
  • now_floor_p:乘客在电梯内的当前楼层。
  • want_floor:乘客想要去的楼层。
  • choice:表示上行或下行的选择。
  • floor_history:记录经过的楼层的向量。

ELEVATOR 类的公有成员函数包括:

  • start():开始电梯系统的运行。
  • ask():询问乘客所在的楼层。
  • arriave_now_floor_p():模拟电梯从当前楼层到达乘客所在楼层。
  • get_choice():让乘客选择上行或下行。
  • get_floor():询问乘客要前往的楼层。
  • judge():判断输入的楼层是否合法。
  • arriave_want_floor():模拟电梯从当前楼层运行到目标楼层。
  • displayFloor():显示经过的楼层信息。
  • displayDate():显示当前日期和时间。
  • saveFloorHistory():将楼层历史记录保存到文件中。

ExpressElevator 类是 ELEVATOR 类的子类,它在构造函数中将 all_floor 变量设置为更高的楼层数,表示快速电梯可以到达更高的楼层。

main 函数中,创建了一个 ELEVATOR 对象 elevator 和一个 ExpressElevator 对象 expressElevator,并分别调用它们的 start() 方法开始运行电梯系统。

整个程序的执行流程是:首先显示当前日期和时间,然后进入一个循环,循环中询问乘客所在楼层,模拟电梯运行到乘客所在楼层,然后询问乘客要前往的楼层,并模拟电梯运行到目标楼层。循环结束后,将楼层历史记录保存到文件中。

运行展示

9bef475f8cef43329793463fd76561b4.png

 图1 电梯控制系统效果图

afb99161c4964692b2def2a83c5cdbab.png

图2 floor_history.txt页面 

总结与体会

本设计针对电梯系统的功能需求进行了实现,主要完成了以下工作:

(1)系统功能设计包括:

  • 输入当前楼层和目标楼层。
  • 根据输入判断电梯运行方向。
  • 电梯运行至目标楼层,并记录经过的楼层。
  • 可以选择继续进行或退出系统。
  • 保存楼层历史记录到文件。

(2)系统软件设计由以下组成:

  • ELEVATOR类:定义了电梯的属性和方法,包括当前楼层、目标楼层、最高楼层、运行方向、楼层历史记录等。
  • ExpressElevator类:继承自ELEVATOR类,可以设置更高的最高楼层数。
  • start()方法:控制整个电梯系统的流程,包括用户输入、电梯运行、保存楼层历史记录等。
  • 其他辅助方法:如输入验证、显示楼层、显示日期和时间等。
  • 本次设计利用了C++的面向对象编程思想和相关库函数,包括iostream、fstream、vector、chrono、thread、ctime等。

(3)完成系统调试:

在设计中,已经添加了基本的输入验证和错误提示机制,并进行了简单的调试和测试。然而,仍然有几处地方需要完善,具体包括:错误处理:对于非法输入或错误操作,需要给出更具体和友好的提示信息,并提供重新输入的机制。功能扩展:根据具体需求,可以添加更多的功能和特性,如静态数据、常数据、动态创建数组或vector模板的应用、继承与派生、多态和文件流等。

 

C++源代码 注重类的交互 片段 #include using namespace std; #include "elevator.h" //Elevator class definition #include "person.h" //Person class definition #include "floor.h" //Floor class definition //constants that represent time required to travel //between floors and direction of the elevator const int Elevator::ELEVATOR_TRAVEL_TIME = 5; const int Elevator::UP = 0; const int Elevator::DOWN = 1; //constructor Elevator::Elevator( Floor &firstFloor, Floor &secondFloor) : elevatorButton( * this ), currentBuildingClockTime( 0 ), moving( false ), direction( UP ), currentFloor( Floor::FLOOR1 ), arrivalTime( 0 ), floor1NeedsService( false ), floor2NeedsService( false ), floor1Ref( firstFloor ), floor2Ref( secondFloor ), passengerPtr( 0 ) { cout << "elevator constrcuted" <<endl; }// end Elevator constructor //destructor Elevator::~Elevator() { delete passengerPtr; cout << "elevator destructed" << endl; }//end Elevator destructor //give time to elevator void Elevator::processTime( int time ) { currentBuildingClockTime = time; if ( moving ) //elevator is moving processPossibleArrival(); else processPossibleDeparture(); if ( !moving ) cout << "elevator at rest on floor " << currentFloor << endl; }// end function processTime // when elevator is moving, determine if it should stop void Elevator::processPossibleArrival() { //if elevator arrives at destination floor if ( currentBuildingClockTime == arrivalTime ) { currentFloor = ( currentFloor == Floor::FLOOR1 ? Floor::FLOOR2 : Floor::FLOOR1); //update current floor direction = ( currentFloor == Floor::FLOOR1 ? UP : DOWN ); //update direction cout << "elevator arrives on floor " << currentFloor <<endl; // process arrival at currentFloor arriveAtFloor( currentFloor == Floor::FLOOR1 ? floor1Ref : floor2Ref); return; }//end if //elevator still moving cout << "elevator moving " << ( direction == UP ? "UP" : "DOWN"
八、 实验内容和要求: 要求根据下面的功能说明描述实现模拟电梯控制软件 (一)电梯配置 1. 共有1个电梯 2. 共有maxfloor层楼层。maxfloor=9。 3. 中间层每层有上下两个按钮,最下层只有上行按钮,最上层只有上行按钮。每层都有相应的指示灯,灯亮表示该按钮已经被按下,如果该层的上行或者下行请求已经被响应,则指示灯灭 4. 电梯内共有maxfloor个目标按钮,表示有乘客在该层下电梯。有指示灯指示按钮是否被按下。乘客按按钮导致按钮指示灯亮,如果电梯已经在该层停靠则该按钮指示灯灭 5. 另有一启动按钮(GO)。当电梯停在某一楼层后,接受到GO信息就继续运行。如果得不到GO信息,等待一段时间也自动继续运行。 6. 电梯内设有方向指示灯表示当前电梯运行方向。 说明:由于本次实验不使用可视化框架,所以无法作到从图形界面上获取按钮请求。因此电梯按钮的设计,不在图形界面上体现,仅用来设计键盘的模拟输入。 (二)电梯的运行控制 1.电梯的初始状态是电梯位于第一层处,所有按钮都没有按下。 2.乘客可以在任意时刻按任何一个目标钮和呼叫钮。呼叫和目标对应的楼层可能不是电梯当前运行方向可达的楼层。 3. 如果电梯正在向I层驶来,并且位于I层与相邻层(向上运行时是I-1层或者向下运行时是I+1层)之间,则因为安全考虑不响应此时出现的I层目标或者请求。如果电梯正好经过了I楼层,运行在I楼层和下一楼层之间,则为了直接响应此时出现的I层目标或者请求,必须至少到达运行方向上的下一楼层然后才能掉头到达I楼层(假设掉头无须其它额外时间),如果I楼层不是刚刚经过的楼层则可以在任意位置掉头,此时掉头后经过的第一个楼层不可停。 4. 电梯系统依照某种预先定义好的策略对随机出现的呼叫和目标进行分析和响应。 5. 乘客数量等外界因素(可能导致停靠时间的长短变化)不予考虑。假设电梯正常运行一层的时间是5S,停靠目标楼层、上下乘客和电梯继续运行的时间是5S。 6. 当电梯停靠某层时,该层的乘客如果错误的按目标或呼叫按钮都不予响应。 7. 电梯停要某一层后,苦无目标和呼叫,则电梯处于无方向状态,方向指示灯全灭,否则电梯内某个方向的指示灯亮,表示电梯将向该方向运行。等接到“GO”信号后电梯立即继续运行。若无GO信号,则电梯在等了上下乘客和电梯继续运行时间后也将继续运行。 8. 当一个目标(呼叫)已经被服务后,应将对应的指示灯熄灭。 (三)电梯运行的控制策略 以下是几个候选策略: 1.先来先服务策略: 将所有呼叫和目标按到达时间排队,然后一一完成。这是相当简单的策略,只需要设计一个将呼叫和目标排队的数据结构。因为该策略效率也很低,所以没有实际的电梯采用这种策略。 2. 顺便服务策略: 顺便服务是一种最常见的简单策略。这种策略在运行控制中所规定的安全前提下,一次将一个方向上的所有呼叫和目标全部完成。然后掉转运行方向完成另外一个方向上的所有呼叫和目标。 可以采用设定目标楼层的办法来实现这个策略,即电梯向一个目标楼层运行,但这个楼层可以修改。具体策略如下: 1) 修改目标楼层的策略: a.如果电梯运行方向向上,那么如果新到一个介于当前电梯所处楼层和目标楼层之间,又可以安全到达的向上呼叫或者目标,将目标楼层修改为这个新的楼层。 b.如果电梯运行方向向下,那么如果新到一个介于当前电梯所处楼层和目标楼层之间,又可以安全到达的向下呼叫或者目标,将目标楼层修改为这个新的楼层。 2)确定新的目标楼层: 如果电梯向上运行,当它到达某个目标楼层后,则依照以下顺序确定下一个目标楼层: a.如果比当前层高的楼层有向上呼叫或者目标,那么以最低的高于当前楼层的有向上呼叫或者目标的楼层为目标。 b.如果无法确定目标楼层,那么以最高的向下呼叫或者目标所在楼层为电梯当前目标楼层。 c.如果无法确定目标楼层,那么以最低的向上呼叫所在楼层为电梯当前的目标楼层。 d.如果仍然不能确定目标楼层(此时实际上没有任何呼叫和目标),那么电梯无目标,运行暂停。 如果电梯向下运行,依照以下顺序确定下一目标楼层: a.如果比当前层低的楼层有向下呼叫或者目标,那么以最高的低于当前楼层的有向下呼叫或者目标的楼层为目标。 b.如果无法确定目标楼层,那么以最低的向上呼叫或者目标所在楼层为电梯当前目标楼层。 c.如果无法确定目标楼层,那么以最高的向下呼叫楼层为目标楼层。 d.如果仍然不能确定目标楼层(此时实际上没有任何呼叫和目标),那么电梯无目标,运行暂停。 3)最快响应策略: 响应所有的现在存在的所有呼叫和目标所需时间(采用不同方案电梯停靠时间相同,所以不必考虑)最短的策略。 可选方案一是电梯先向上运行响应经过各层的目标和向上呼叫,再向下运行响应所有向下呼叫以及途经各层的目标,最后再向上响应剩余的向上呼叫。二是恰好相反,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夏天是冰红茶

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

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

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

打赏作者

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

抵扣说明:

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

余额充值