前言
第一次接触Ubuntu系统,会有一种迷芒。它不像window系统一样比较简单易操作,所以下面我将用黑马程序员中的一个例子———职工管理系统,尝试一下教大家如何在Ubuntu系统下如何创建一个C++项目,以及创建C++文件和对其进行编译。当然最主要的是职工管理系统的代码。由于我是学没多久,会有些出错或者不会,希望多多包涵。
一、在Ubuntu系统下用Make创建一个C++项目
在Windows系统下,我们可以使用Visual Studio等IDE帮助我们构建一个C++工程项目,如何在Ubuntu系统下创建项目呢?我将使用make和gedit构建一个C++工程项目
1.首先当然是创建一个文件夹,通过mkdir创建项目根目录,这个文件夹就是项目(当然现在还不是项目)
mkdir 基于多态的职工管理系统
2.进入这个文件夹,创建C++文件
cd 基于多态的职工管理系统/
gedit 职工管理类.h
gedit 职工管理类.cpp
gedit 职工管理系统.cpp
3.在三个文件写代码,现在还不需要,可以先不管
4.在./基于多态的职工管理系统 目录下,使用gedit编辑一个名为Makefile或者makefile的文件
cd 基于多态的职工管理系统/
gedit Makefile #gedit makefile也是可以的,命令make会在当前目录下寻找Makefile或者makefile
- Makefile内容如下
all:
g++ 职工管理系统.cpp 职工管理类.cpp -o app -std=c++11
clean:
rm app
记住g++和rm前面需要用tab键,不是用空格,要不然会报错
解释一下g++ 职工管理系统.cpp 职工管理类.cpp # 使用g++编译器编译当前所有的cpp文件,主Cpp文件(就是那个有main主函数那个cpp文件)一定要放在第一个
-o app # 参数-o表示最终生成的可执行文件为app
-std=c++11 # 用于支持c++11的标准,-std=gnu++11用于支持c++11标准和gnu扩展特性
rm app # 删除app
在当前目录下执行命令make
make # 执行make,就可以构建C++项目
./app # 执行生成的app文件,可以看到最后的结果
里面应该有这几个文件,除了那个脚本(.sh)
二、在Ubuntu系统下用脚本实现按任意键继续的操作
1.什么是脚本
这是我上网查的(可以跳过不看)
百科解释:
脚本(script)是使用一种特定的描述性语言,依据一定的格式编写的可执行文件,又称作宏或批处理文件。
脚本通常可以由应用程序临时调用并执行。各类脚本目前被广泛地应用于网页设计中,因为脚本不仅可以减小网页的规模和提高网页浏览速度,而且可以丰富网页的表现,如动画、声音等。举个最常见的例子,当我们点击网页上的E-mail地址时能自动调用Outlook Express或Foxmail这类邮件软件,就是通过脚本功能来实现的。也正因为脚本的这些特点,往往被一些别有用心的人所利用。例如在脚本中加入一些破坏计算机系统的命令,这样当用户浏览网页时,一旦调用这类脚本,便会使用户的系统受到攻击。所以用户应根据对所访问网页的信任程度选择安全等级,特别是对于那些本身内容就非法的网页,更不要轻易允许使用脚本。通过“安全设置”对话框,选择“脚本”选项下的各种设置就可以轻松实现对脚本的禁用和启用。
通俗解释:
脚本(Script)的意思最早是从演艺界来的。如果没有脚本,该怎么表演? 表演者只能即兴发挥,或者靠导演的口述来进行。
有了脚本,带来的最大变化是什么?
- 可重复。也就是说,有了脚本,可以把我们既定的一个规程不断重复。
- 脚本需要人来执行。因此脚本的执行效率与具体的执行人有关系。
- 如果在表演过程中,商定了某种大家认可的修改,会考虑对脚本进行修改,用以将我们修改的意图记录下来,将来的再现就可以反映这个修改。
对于 IT 行业,脚本这个词,是个绝妙的翻译。他贴切的表达了这几个含义(web前端开发中scripts文件下有.js文件就是脚本)。
- 脚本的用意是为了可再现的重复一个设定好的规程。
- 脚本需要有一个解释器来执行。
- 脚本能够方便的,快速的,经常的被修改。
所以说,要是打比喻:
你打开资源管理器,用鼠标把一个文件拖到另外一个地方,这是即兴表演。
你写几行命令,把他保存下来, 一执行就做了上面的事情,这就是脚本。
即兴表演,你重复100次,累死了。
脚本,你重复执行100次,全是计算机搞定了
2.创建一个脚本来代替实现window下的system(“pause”)
首先需要进入到你的C++文件同一个文件夹创建脚本
gedit 实现按任意键继续操作.sh
写入
#!/bin/bash
#实现按任意键操作的脚本文件
#-s 指输入的字符屏幕上不可件,应该说可见,但由于和终端的背景色相同,故不可见了
#-n1 看到n后那个“1”了没,表示仅接收1个字符,按回车键也属于一个字符
#-p是指后面可加用“ ”括起来的提示符
read -s -n1 -p "按任意键继续 ... "
然后在需要用到的C++代码上用system("./实现按任意键继续操作.sh");来代替system(“pause”);
system("./实现按任意键继续操作.sh");
三、代码展示
1.职工管理系统.cpp
#include <iostream>
#include "职工管理类.h"
using namespace std;
#include "worker.h"
#include "普通职工.h"
#include "经理.h"
#include "老板.h"
int main()
{
//实例化管理者对象
WorkerManager wm;
int choice;
while(true)
{
//调用展示菜单成员函数
wm.Show_Menu();
cout << "请输入您的选择:" << endl;
cin >> choice;
switch(choice)
{
case 0:
wm.ExitSystem(); //退出操作
break;
case 1:
wm.Add_Emp(); //添加职工
break;
case 2:
wm.Show_Emp(); //展示职工
break;
case 3:
wm.Del_Emp(); //删除职工
break;
case 4:
wm.Mod_Emp(); //修改职工
break;
case 5:
wm.Find_Emp(); //查找职工
break;
case 6:
wm.Sort_Emp(); //按职工编号排序
break;
case 7:
wm.Clean_file(); //清空文件
break;
default:
system("clear"); //清屏操作
break;
}
}
system("./实现按任意键继续操作.sh");
return 0;
}
2.职工管理类.h
#pragma once //防止头文件重复包含
#include <iostream>
#include "worker.h"
#include "worker.h"
#include "普通职工.h"
#include "经理.h"
#include "老板.h"
#include <fstream>
#define FILENAME "职工信息.txt"
using namespace std;
class WorkerManager
{
public:
WorkerManager();//构造函数
void Show_Menu(); //菜单函数
void ExitSystem(); //退出系统函数
int m_EmpNum; //记录职工人数
Worker ** m_EmpArray; //职工数组指针
void Add_Emp(); //添加职工
void save(); //保存文件
bool m_FileIsEmpty; //判断文件是否为空 标志
int get_EmpNum(); //统计文件中人数
void init_Emp(); //初始化员工
void Show_Emp(); //显示职工
void Del_Emp(); //删除职工
int IsExist(int id); //判断职工是否存在 如果存在返回职工所在的数组中的位置,不存在返回-1
void Mod_Emp(); //修改职工
bool IdIsRepeat(int id); //判断职工编号是否重复
void Find_Emp(); //查找职工
void Sort_Emp(); //按编号进行排序
void Clean_file(); //清空文件
~WorkerManager();//析构函数
};
3.职工管理类.cpp
#include "职工管理类.h"
WorkerManager::WorkerManager()
{
//1.文件不存在
ifstream ifs;
ifs.open(FILENAME, ios::in); //读文件
if(!ifs.is_open())
{
//cout << "文件不存在" << endl;
//初始化属性
//初始化记录人数
this->m_EmpNum = 0;
//初始化数组指针
this->m_EmpArray = NULL;
//初始化文件是否为空
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//2.文件存在 数据为空
char ch;
ifs >> ch;
if(ifs.eof())
{
//文件为空
//cout << "文件为空" << endl;
//初始化属性
//初始化记录人数
this->m_EmpNum = 0;
//初始化数组指针
this->m_EmpArray = NULL;
//初始化文件是否为空
this->m_FileIsEmpty = true;
ifs.close();
return;
}
//3.当文件存在,并且记录数据
int num = this->get_EmpNum();
//cout << "职工人数:" << num << endl;
this->m_EmpNum = num;
this ->m_EmpArray = new Worker*[this->m_EmpNum]; //开辟空间
this->init_Emp(); //将文件中的数据,存放在数组中
}
void WorkerManager::Show_Menu() //菜单函数
{
cout << "-----------------------------------" << endl;
cout << "--------欢迎使用职工管理系统--------" << endl;
cout << "-----------0.退出管理系统-----------" << endl;
cout << "-----------1.增加职工信息-----------" << endl;
cout << "-----------2.显示职工信息-----------" << endl;
cout << "-----------3.删除离职职工-----------" << endl;
cout << "-----------4.修改职工信息-----------" << endl;
cout << "-----------5.查找职工信息-----------" << endl;
cout << "-----------6.按照编号排序-----------" << endl;
cout << "-----------7.清空所有文档-----------" << endl;
cout << "-----------------------------------" << endl;
cout << endl;
}
void WorkerManager::ExitSystem()
{
cout << "欢迎下次使用" << endl;
system("./实现按任意键继续操作.sh");
exit(0); //退出程序
}
void WorkerManager::Add_Emp()
{
cout << "请输入添加职工数量: " << endl;
int addNum= 0; //保存用户输入的数量
cin >> addNum;
if(addNum > 0)
{
//添加
//计算添加新空间的大小
int newSize = this->m_EmpNum + addNum; //新空间大小 = 原来记录人数 + 新增人数
//开辟新空间
Worker ** newSpace = new Worker*[newSize];
//拷贝
if(this->m_EmpArray != NULL)
{
for(int i = 0; i < this->m_EmpNum; i++)
{
newSpace[i] = m_EmpArray[i];
}
}
//批量增加新数据
for(int i = 0; i < addNum; i++)
{
int id;
string name;
int dSelect;
while(1)
{
cout << "请输入第" << i+1 << "个新职工编号" << endl;
cin >> id;
if(this->IdIsRepeat(id)) //为真,提醒用户编号已经存在,重新输入
{
cout << "职工编号已存在,请重新输入!" << endl;
}
else
{
break;
}
}
cout << "请输入第" << i+1 << "个新职工姓名" << endl;
cin >> name;
cout << "请选择该职工的岗位:1.普通员工 2.经理 3.老板" << endl;
cin >> dSelect;
Worker *worker = NULL;
switch(dSelect)
{
case 1:
worker = new Employee(id, name, 1);
break;
case 2:
worker = new Manager(id, name, 2);
break;
case 3:
worker = new Boss(id, name, 3);
break;
default:
break;
}
//将创建的职工指针保存到数组中
newSpace[this->m_EmpNum+i] =worker;
}
//释放原有空间
delete[] this->m_EmpArray;
//更改新空间指向
this->m_EmpArray = newSpace;
//更新记录人数
this->m_EmpNum = newSize;
//更新职工不为空标志
this->m_FileIsEmpty = false;
//提示用户添加成功
cout << "成功添加" << addNum << "名新职工" << endl;
this->save();//保存数据
}
else
{
cout << "输入数据有误" << endl;
}
//按任意键回到上级目录
system("./实现按任意键继续操作.sh");
system("clear");
}
//保存文件
void WorkerManager::save()
{
ofstream ofs;
ofs.open(FILENAME,ios::out); //写文件
//将每个人的数据写入文件中
for(int i = 0; i < this->m_EmpNum; i++)
{
ofs << this->m_EmpArray[i]->m_Id << " " << this->m_EmpArray[i]->m_Name << " " << this->m_EmpArray[i]->m_DeptId << endl;
}
//关闭文件
ofs.close();
}
//统计文件中人数
int WorkerManager::get_EmpNum()
{
ifstream ifs;
ifs.open(FILENAME, ios::in); //打开文件 读文件
int id;
string name;
int dId;
int num = 0;
while(ifs >> id && ifs >> name && ifs >> dId)
{
//统计人数变量
num++;
}
return num;
}
//初始化员工
void WorkerManager::init_Emp()
{
ifstream ifs;
ifs.open(FILENAME, ios::in);
int id;
string name;
int dId;
int index = 0;
while(ifs >> id && ifs >> name && ifs >> dId)
{
Worker *worker = NULL;
if (dId == 1) //普通职工
{
worker = new Employee(id,name,dId);
}
else if(dId == 2) //经理
{
worker = new Manager(id,name,dId);
}
else //老板
{worker = new Boss(id,name,dId);}
this->m_EmpArray[index] = worker;
index++;
}
ifs.close();
}
//显示职工
void WorkerManager::Show_Emp()
{
//判断文件是否为空
if(this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
}
else
{
for(int i = 0; i < m_EmpNum; i++)
{
//利用多态调用程序接口
this->m_EmpArray[i]->ShowInfo();
}
}
//按任意键后清屏
system("./实现按任意键继续操作.sh");
system("clear");
}
//删除职工
void WorkerManager::Del_Emp()
{
if(this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
}
else
{
int id;
//按编号删除职工
cout << "请输入想要删除职工的编号:" << endl;
cin >> id;
int index;
index = this->IsExist(id);
if(index!=-1) //说明职工存在
{
for(int i = index; i < this->m_EmpNum-1; i++)
{
this->m_EmpArray[i] = this->m_EmpArray[i+1];
} //数据前移,覆盖式删除
this->m_EmpNum--; //更新职工人数
this->save(); //更新到文件中
cout << "删除成功!" << endl;
}
else
{
cout << "删除失败,没有该职工!" << endl;
}
}
//按任意键后清屏
system("./实现按任意键继续操作.sh");
system("clear");
}
//修改职工
void WorkerManager::Mod_Emp()
{
if(this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
}
else
{
//按编号修改职工
int id;
cout << "请输入修改职工的编号:" << endl;
cin >> id;
int ret = this->IsExist(id);
if(ret!=-1)
{
//查到该编号的职工
delete this->m_EmpArray[ret];
int newId = 0;
string newName = "";
int dSelect = 0;
cout << "查到" << id << "号职工" << endl;
while(1)
{
cout << "请输入想要修改职工的编号:" << endl;
cin >> newId;
if(this->IdIsRepeat(newId)) //为真,提醒用户编号已经存在,重新输入
{
cout << "职工编号已存在,请重新输入!" << endl;
}
else
{
break;
}
}
cout << "请输入新职工姓名:" << endl;
cin >> newName;
cout << "请输入新岗位" << endl;
cout << "1.普通职工" << endl;
cout << "2.经理" << endl;
cout << "3.老板" << endl;
cin >> dSelect;
Worker *worker = NULL;
switch(dSelect)
{
case 1:
worker = new Employee(newId,newName,dSelect);
break;
case 2:
worker = new Manager(newId,newName,dSelect);
break;
case 3:
worker = new Boss(newId,newName,dSelect);
break;
default:
break;
}
this->m_EmpArray[ret] = worker; //更新数据到数组中
cout << "修改成功!" << endl;
this->save(); //保存在文件中
}
else
{
cout << "修改失败,查无此人!" <<endl;
}
//按任意键后清屏
system("./实现按任意键继续操作.sh");
system("clear");
}
}
//查找职工
void WorkerManager::Find_Emp()
{
if(this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
}
else
{
int select = 0;
cout << "请输入你想要查找的方法:" << endl;
cout << "1.按职工编号查" << endl;
cout << "2.按职工姓名查" << endl;
cin >> select;
if(select == 1) //按职工编号查
{
cout << "请输入你想要查找职工的编号:" << endl;
int id;
cin >> id;
int ret = IsExist(id);
if(ret!=-1) //查找成功,有该职工
{
cout << "查找成功,该职工信息如下:" << endl;
this->m_EmpArray[ret]->ShowInfo();
}
else
{
cout << "查无此人" << endl;
}
}
else if(select == 2) //按职工姓名查
{
string name;
cout << "请输入查找的姓名:" << endl;
cin >> name;
bool flag = false; //判断是否查到此人的标志
for(int i = 0; i < m_EmpNum; i++)
{
if(this->m_EmpArray[i]->m_Name == name)
{
cout << "查找成功,职工编号为 " << this->m_EmpArray[i]->m_Id << "号职工信息如下" << endl;
flag = true;
this->m_EmpArray[i]->ShowInfo();
}
}
if(flag==false)
{
cout << "查无此人" << endl;
}
}
else
{
cout << "输入选项有误!" << endl;
}
}
//按任意键后清屏
system("./实现按任意键继续操作.sh");
system("clear");
}
//判断职工是否存在 如果存在返回职工所在的数组中的位置,不存在返回-1
int WorkerManager::IsExist(int id)
{
int index = -1;
for(int i = 0; i < this->m_EmpNum; i++)
{
if(this->m_EmpArray[i]->m_Id == id)
{
index = i; //找到职工,并返回编号
break;
}
}
return index;
}
//判断职工编号是否重复,是返回真,否返回假
bool WorkerManager::IdIsRepeat(int id)
{
for(int i = 0; i < this->m_EmpNum; i++)
{
if(this->m_EmpArray[i]->m_Id == id)
{
return true;
}
}
return false;
}
//按编号进行排序
void WorkerManager::Sort_Emp()
{
if(this->m_FileIsEmpty)
{
cout << "文件不存在或者记录为空" << endl;
//按任意键后清屏
system("./实现按任意键继续操作.sh");
system("clear");
}
else
{
cout << "请选择排序方式:" << endl;
cout << "1.按照职工编号进行升序" << endl;
cout << "2.按照职工编号进行降序" << endl;
int select = 0;
cin >> select;
for(int i = 0; i < this->m_EmpNum; i++)
{
int MinOrMax = i; //声明一个最小或者最大值下标
for(int j = i+1; j < this->m_EmpNum; j++)
{
if(select == 1) //升序
{
if(this->m_EmpArray[MinOrMax]->m_Id > this->m_EmpArray[j]->m_Id)
{
MinOrMax = j;
}
}
else if(select == 2) //降序
{
if(this->m_EmpArray[MinOrMax]->m_Id < this->m_EmpArray[j]->m_Id)
{
MinOrMax = j;
}
}
else
{
cout << "输入有误!" << endl;
break;
}
}
if(i != MinOrMax) //判断一开始认定 最大最小值是不是计算的最大最小值,不是交换数据
{
Worker *temp = this->m_EmpArray[i];
this->m_EmpArray[i] = this->m_EmpArray[MinOrMax];
this->m_EmpArray[MinOrMax] = temp;
}
}
cout << "排序成功!排序后的结果为:" << endl;
this->save(); //排序后保存在文件中
this->Show_Emp(); //展示职工
}
}
//清空文件
void WorkerManager::Clean_file()
{
cout << "确定清空?" << endl;
cout << "1.确定" << endl;
cout << "2.返回" << endl;
int select = 0;
cin >> select;
if(select == 1)
{
//清空文件
ofstream ofs(FILENAME,ios::trunc); //删除文件后重新创建
ofs.close();
if(this->m_EmpArray != NULL)
{ //删除堆区的每个职工对象
for(int i = 0; i < this->m_EmpNum; i++)
{
delete this->m_EmpArray[i];
this->m_EmpArray[i] = NULL;
}
delete[]this->m_EmpArray; //删除堆区数组指针
this -> m_EmpArray = NULL;
this -> m_EmpNum = 0;
this -> m_FileIsEmpty = true;
}
cout << "清空成功!" << endl;
}
//按任意键后清屏
system("./实现按任意键继续操作.sh");
system("clear");
}
WorkerManager::~WorkerManager()
{
if(this->m_EmpArray != NULL)
{
for(int i = 0; i < this->m_EmpNum; i++)
{
if(this->m_EmpArray[i] != NULL)
{
delete this->m_EmpArray[i];
}
}
delete[] this->m_EmpArray;
this->m_EmpArray = NULL;
}
}
4.worker.h
#pragma once
#include <iostream>
#include <string>
using namespace std;
//职工抽象类
class Worker
{
public:
virtual void ShowInfo() = 0; //显示人的信息的纯虚函数
virtual string getDeptName() = 0; //获取岗位名称的纯虚函数
int m_Id; //职工编号
string m_Name; //职工姓名
int m_DeptId; //部门编号
};
5.老板.h and 老板.cpp
#pragma once
#include <iostream>
#include "worker.h"
using namespace std;
class Boss:public Worker
{
public:
Boss(int id, string name, int dId); //构造函数
virtual void ShowInfo(); //显示人的信息
virtual string getDeptName(); //获取岗位名称
};
#include "老板.h"
//构造函数
Boss::Boss(int id,string name,int dId)
{
this -> m_Id = id;
this -> m_Name = name;
this -> m_DeptId = dId;
}
//显示个人信息
void Boss::ShowInfo()
{
cout << "职工编号:" << this->m_Id << "\t职工姓名:" << this->m_Name << "\t岗位:" << this->getDeptName() << endl;
}
//获取岗位名称
string Boss::getDeptName()
{
return string("老板");
}
6.经理.h and 经理.cpp
#pragma once
#include <iostream>
#include "worker.h"
using namespace std;
class Manager:public Worker
{
public:
Manager(int id, string name, int dId); //构造函数
virtual void ShowInfo(); //显示人的信息
virtual string getDeptName(); //获取岗位名称
};
#include "经理.h"
//构造函数
Manager::Manager(int id,string name,int dId)
{
this -> m_Id = id;
this -> m_Name = name;
this -> m_DeptId = dId;
}
//显示个人信息
void Manager::ShowInfo()
{
cout << "职工编号:" << this->m_Id << "\t职工姓名:" << this->m_Name << "\t岗位:" << this->getDeptName() << endl;
}
//获取岗位名称
string Manager::getDeptName()
{
return string("经理");
}
7.普通职工.h and 普通职工.cpp
//普通职工类头文件
#pragma once
#include <iostream>
#include <string>
#include "worker.h"
using namespace std;
class Employee:public Worker
{
public:
Employee(int id, string name, int dId);
virtual void ShowInfo(); //显示人的信息
virtual string getDeptName(); //获取岗位名称
};
#include "普通职工.h"
#include <string>
//构造函数
Employee::Employee(int id, string name, int dId)
{
this -> m_Id = id;
this -> m_Name = name;
this -> m_DeptId = dId;
}
//显示个人信息
void Employee::ShowInfo()
{
cout << "职工编号:" << this->m_Id << "\t职工姓名:" << this->m_Name << "\t岗位:" << this->getDeptName() << endl;
}
//返回岗位名称
string Employee::getDeptName()
{
return string("员工");
}
8.Makefile
all:
g++ 职工管理系统.cpp 职工管理类.cpp 普通职工.cpp 经理.cpp 老板.cpp -o app -std=c++11
clean:
rm app
四、测试代码
g++ 职工管理系统.cpp 职工管 理类.cpp 普通职工.cpp 经理.cpp 老板.cpp -o app -std=c++11
./app