热门推荐
C++小系统——餐馆员工管理系统及餐馆点菜系统(一)
2024-12-31 21:22

    总算是把这个小系统给写完了,写的时间有点长(主要是中间过程遇到很多杂事,导致思路断断续续的,一直没怎么写)。

    这篇博客,我主要来讲,我在写的过程中遇到的错误,处理方法,以及部分细节。

    (源码及GitHub地址会在文末给出

    1| 如何使用光标移动操作
        我就先贴这几段代码作为样例
 
 

   

 

    呃~~感觉不放效果图不好解释(下面是最终效果图,我们先只看蓝色部分

    强调一点,我这个蓝色部分的布局是用一维数组做+SetConsoleCursorPosition()  (API中的光标定位函数,用法见<SetConsolePosition()用法简析>),当然也可以用二维数组做,只不过二维数组用起来肯定没一维数组那么简单。

    好了,我们现在已经了解到用一维数组做,用SetConsoleCursorPosition()定好位之后,我们就该开始分析键盘的移动。

    (如果不用SetConsoleCursorPosition的话,一维数组输出基本上是处于一行

    初始光标的数组下标为0时,也就是图中的可乐鸡翅的位置,它现在只有两个位置可以移动,即:向下,向右。

    向下: i+1

    向右: i+5

    (我们先暂且这样想,后面看到<SetConsolePosition()用法简析>你就知道为什么是”暂且“了)

    那如何判断当数组下标处于0时,不能往上或往左移呢?我们思路肯定都有,主要是如何具体实现这一操作,参考前面的第二段代码,如

 

我先用getch)函数 和 整型变量ch ,来获取键盘键入的ASCII码值(UP已在枚举里赋值,当键入方向键“↑”时,便开始判断 *thisIndex (这是下标当前索引值,个人认为*thisIndex用的是比较好的,它直接修改所对应的内存空间的值,省去去了各个函数之间调用传值的麻烦,若*thisIndex值大于0,这代表它可以向右或向上动 ,然后对*thisIndex的值进行修改,展示函数通过循环,获取thisindex的值,便可出现效果。

  2| SetConsoleCursorPosition() & SetConsoleTextAttribute()

    考虑到后面需要很多这样的API函数来进行过渡介绍,暂时先介绍这两个,稍微了解一下就OK了,后面若是再出现其他的,我会直接在文中给出介绍,不再单独列出说明。

 

    # setConsoleCursorPosition() 设置光标打印位置

    1.设置句柄

 

    2.设置COORD

   在这里多说一句,COORD其实就是一个结构,里面含有X,Y的成员变量注意是大写) 

 

    3.设置位置坐标值

    4.SetConsoleCursorPosition() 
 

    5.输出语句

 

    # setConsoleTextAttribute() 设置文本的属性

    1.setConsoleTextAttribute

    格式:setConsoleTextAttribute(句柄,颜色配置);

    若想单独使用这个函数,那它前面只需上面介绍的API的第一个步骤就OK了,但是相同点是,仍要在输出语句前设置。 


    颜色搭配可以参考这篇博客,这应该是最全的了吧~

    https://blog.csdn.net/qq_36642226/article/details/76690423


    2.5| 留个小空白给你

    若是你按照上面的做法去做,你会发现你的“菜单”的每行每列都紧紧的挨在一起了。

    那么,该如何解决这个问题呢呢?这个问题留给你自己思考,若是实在不会,你可以去文末的我留的github地址去clone一下我的文件,然后在menu.h头文件里,你就会找到答案啦。

   

    思路

    #状态栏:我需要在状态栏实现三个操作

                      1.选菜数量输入

                      2.撤销上一次选菜操作

                      3.撤销提醒

    ##选菜栏:在选菜栏里,我需要实现两个操作

                      1.选中后的菜名的显示及金额的显示

                      2.菜名的增加与消除

    ###选用的方法

                      综合考虑前两个步骤,我决定在这里使用vector数组+结构体

                      1.选用vector数组的思想,在这里用vector去实现菜名的增加与当前金额的变化

                        相比较普通数组而言是很简单的。

                        再者,我已在前面说过菜单用一维数组解决,那vector是最方便和高效的

                       2.用结构体,是因为需要同时显示菜名及计算金额,单纯的数组只可以存储一种类型的值

                         而在这里,结构体就可以帮上很大的忙。

    ####难点

                       1.如何将vector数组+结构体结合使用。

    做法

    思路现在是有了,关键就是在于如何去做。

    先看“添加”操作

    我们先定义一个showStorage的结构体,里面成员变量有 
sName(菜名sCopies(数量sPrice(单价)。 
(其实这里的单价最好用double定义,当时只是为了完成这个系统,没考虑太多 

    然后用vector声明一个showStorage类型的变量sStorage。

    再来看看我们的操作机制,“SPACE”是确认键,“TAB”是撤销键。

    先看“SPACE”键

 

     这是SPACE的功能,先说明一点这里的cou  是真的没有用。你可能会问:那你为什么要写啊 , 还把它加进函数里? 咳咳......这个......因为程序员的迷信...... 事情是这样的:我最后检查时,发现这里的cou没用,当时就一个个全部删除了,嗯?运行。 控制台一堆乱码。还好,我有备份。嗯。再来一次。乱码。

    当时就开始慌了,删cou前,备份运行完美;删cou后,就炸了。。。没办法了,开始分析错误。

我知道可能数组越界,但不知道越界的那个数组在哪里?QAQ 找了好久,发现前面的某个地方的for循环里的判断条件多出来一个‘=’(问号脸.jpg)。。。然后,我就再不敢动程序里这根“龙脉”了。。。

    思维回来一下(正经.jpg,可以看到这里,我按下“SPACE”,switch结构会根据thisIndex的值进行判断。

    这里,我出现一个多余的写法,就是用switch,这里改为一个inputValue(cou,thisIndex;就好了。

    (源程序里面可能没改,我们知道就好了

    接下来看看inputValue函数的定义

 

kind这个数组在menu.h里面

 

可以看到这里 我们也是用结构体数组预先存储菜名,单价。

中间怎么有个“{ },”?哈哈,这就是2.5的答案啦!自己去试试吧


对于inputValue)函数,我主要讲一下vector结构体的获取数值的方法

               1.先定义一个对象

                         可以看到我这里定义了一个showStorage类型的tag对象

               2.再用对象分别获取结构体里每个成员变量的值

                         如:   tag.sName = kind[thisIndex].name;

               3.最后把这个tag对象加入vector的后面就可以了(这里考虑到“撤销”步骤的顺序性

                 所以依次加入vector数组尾部

                          sStorage.push_back(tag);

    到这里,“添加”步骤就基本完成啦,具体文本放的位置和方法,你照着上面的说明去操作就是了,这里就不详细说啦。

    接下来看“撤销”操作。

    “撤销”操作就比“添加”简单多了。估计我代码一放出来,你就明白了。

 

    直接erase就好了,什么!具体erase用法

    你慢慢看,我就不多解释了。http://www.cplusplus.com/reference/vector/vector/erase/

    ENTER键详细的解说都已经放在代码里了

 

    我们再次思考一下代码中的问题。

    如果,我们每次用完vector后不清空数据的话,那么它的数据就会一直存在(当然前提是程序继续运行)。

    所以,我们必须要在每次“提交”后,对vector进行清空,以保证数据不会留存到下一次操作。

    若是不这样做,我感觉顾客会打死你。。。:D

    我们既然聊到打印,就先看看原理。

    头文件  : #include <fstream>

    具体 

             fstream();              //打开文件供读写

             ifstream()              //向已有文件读入

             ofstream()             //向文件写入

             常用打开模式

                                  ios: :in                //只读

                                  ios: :out              //只写

                                  ios: :app             //从文末开始写

                                  ios: :trunc           //打开一个文件,清空内容再开始写

    下面我贴出基本格式

 

    ofstream File ("文件名.txt" , 打开模式 )

    if(打开文件失败){

           //退出或其他操作

    }

    else{

           //你需要的操作

    }

    outFile.close();      //关闭文件

    //“读入文件”就把ofstream改为ifstream就好了。

    读写大致框架就是以上,当然还有其他的写法,这里不一 一罗列。

    下面看看读写细节。

    “写入”细节

                         outFile<<你要写入的东西<<endl;

                         写入部分就和常规cout一样,若不加endl,就会导致文件全部写在一行

                         这里可根据自己需求   进行处理。

    “读入”细节

                        string Str , readStr;

                        ......

                        inFile>>readStr;

                        Str = readStr;

    这里的Str是用来被赋值的对象,我仅仅简写为Str(根据所处情况,灵活运用)。readStr,是用来获取读入的值。

        头文件:#include<sstream>

        我基本上把这两个作为模板套进去了,可以做下笔记~~

 

~~~~(一)就先写到这里 ,最近忙于期末考试(斜眼笑.jpg,等有时间把(二)也写了。。。

 在(二)里面,我会写关于员工系统与餐馆管理系统的数据共用及修改。

okl,就先到这   :-)

github:https://github.com/Diomchen/THE(记得给个小星星哦~




    以上就是本篇文章【C++小系统——餐馆员工管理系统及餐馆点菜系统(一)】的全部内容了,欢迎阅览 ! 文章地址:https://sicmodule.kub2b.com/quote/17279.html 
     栏目首页      相关文章      动态      同类文章      热门文章      网站地图      返回首页 企库往资讯移动站https://sicmodule.kub2b.com/mobile/,查看更多   
发表评论
0评