好家伙
1. 题目要求
一、 课程设计(大作业)目的
熟悉Linux编程环境,加强对Linux命令的理解及函数的运用,完成一个操作系统的部分系统的设计过程、编码、调试,锻炼实际应用能力。
二、 课程设计(大作业)具体要求
2.1 课程设计题目
在Linux环境下模拟实现简单命令解释器。
(1)要求实现的基本命令包括:
pwd //显示当前所在目录的路径名
list <目录名> //列出指定目录名中的所有目录及文件
modifydir <目录名或路径> //改变当前工作目录
makedir <目录名> //新建目录
deldir <目录名> //删除目录
exit //退出命令解释程序
(2)可选做的扩展命令包括:
rename <旧文件名> <新文件名> //重命名一个文件或目录
copy <已存在的文件名> <副本文件名或路径> //复制一个已存在的文件
find <目录> -name <待查找的文件名> //在指定的目录及其子目录中查找指定的文件,并输出查找到的文件的绝对路径。
(3)提示:整个程序的大致框架可参考如下:
while ( exit未被输入 )
{ 接收键盘的一行输入
分析输入的命令
对输入的命令进行处理,调用系统函数实现功能
}
2.2 设计要求
(1) 设计必须在Linux环境下进行。
(2) 命令解释程序的提示符为:姓名拼音@
(3) 程序编写中不得使用system()系统调用。
(4) 整个程序必须严格经过测试,完成所有基本功能。源程序应有较详尽的注释。
2.3可能用到的系统函数:
open(),close(),read(),write(),creat()
chdir(), opendir(),readdir(),rewinddir(),closedir(),rmdir(),mkdir()
getcwd(), ftw()
2.思路以及代码
看上去非常难,实际上只需要把关键函数再封装一遍就好了
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<dirent.h>
#include<fcntl.h>
#include<time.h>
using namespace std;
int C_fd; //文件描述符
char filename[100]; //文件名
int isopen = 0; //打开状态
char *pargv[5] = {"ls", "-l", NULL, NULL};
char findFileName[50]={""}; //用于存放要查找的文件名
int fileFlag = 0; //用于标记是否找到查找的文件名
int num=0;
string file;
//显示当前所在目录的路径名 mypwd
void mypwd() {
char path[100];
getcwd(path,100);
cout<<"当前目录: "<<path<<endl;
}
//列举指定目录中的所有目录及文件 mylist
//用函数opendir()打开目录,并且用readdir()函数读取每一个目录节点,打印输出信息,最后用函数closer()关闭
bool mylist(string dir) {
DIR* d = opendir(dir.c_str());
if(d==NULL) {
return false;
} else {
struct dirent *dirent;
while(dirent=readdir(d)) {
cout<<endl;
cout<<" "<<dirent->d_name<<" "<<dirent->d_type<<" "<<dirent->d_reclen<<endl;
cout<<endl;
}
closedir(d);
return true;
}
}
//显示当前日期-mydate
void date()
{
time_t timeval;
(void)time(&timeval);
string timestr;
// invoke the ctime fuction and return the string
timestr = ctime(&timeval);
cout<<"当前时间: "<<timestr<<endl;
}
// 改变当前目录-mycd
bool mycd(string path) {
if(chdir(path.c_str())==0) {
return true;
} else {
return false;
}
}
//新建目录-mymkdir
bool mymkdir(string dir) {
if(mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH)==0) {
return true;
} else {
return false;
}
}
//删除目录-myrmdir
bool myrmdir(string dir) {
if(rmdir(dir.c_str())==0) {
return true;
} else {
return false;
}
}
//重命名文件或目录-myrename
bool myrename(string lastname,string newname) {
if(rename(lastname.c_str(),newname.c_str())==0) {
return true;
} else {
return false;
}
}
//复制文件-mycopy
//先判断文件是否存在,存在则在原来要复制的文件名后加(1),否则直接复制
bool mycopy(string existname,string newname) {
int fo1,fo2;
char buf[1024];
fo1=open(existname.c_str(),O_RDONLY);
if(fo1==-1) {
return false;
} else {
fo2=open(newname.c_str(),O_RDONLY);
if(fo2!=-1) {
int i;
cout<<"确定替换文件?"<<endl;
cout<<"输入1为确定,非1为否定.";
cin>>i;
if(i!=1) {
newname+="(1)";
}
close(fo2);
}
fo2=open(newname.c_str(),O_WRONLY|O_CREAT,S_IRWXU);
int size = read(fo1,buf,sizeof(buf));
write(fo2,buf,size);
close(fo1);
close(fo2);
return true;
}
}
//创建文件功能-- mycreat(open打开文件)
void creatopen()
{
cout<<"请输入要打开/创建的文件名: "<<endl;
cin>>filename;
C_fd = open(filename, O_RDWR|O_TRUNC, 0666);
if (C_fd >= 0)
{
isopen = 1, cout<<"该文件已存在,打开成功"<<endl;
pargv[2] = (char *)malloc(50);
strcpy(pargv[2], filename);
}
else
{
C_fd = open(filename, O_CREAT|O_RDWR|O_TRUNC,0666);
if (C_fd >= 0)
isopen = 1, cout<<"该文件不存在,新建成功:"<<endl;
else
isopen = 0, cout<<"打开/新建失败"<<endl;
}
}
//创建文件功能-- mycreat(write写入文件内容)
void creatwrite()
{
char buffer[1024];
cout<<"请输入文件内容(按回车保存):"<<endl;
cin>>buffer;
int t = write(C_fd, buffer, strlen(buffer));
if (t == -1)
cout<<"保存失败!"<<endl;
else
cout<<"保存成功!"<<endl;
cout<<"该文件内容为:";
cout<<buffer<<endl;
}
//删除文件-mydelete
bool mydelete(string dir) {
if(unlink(dir.c_str())==0) {
return true;
} else {
return false;
}
}
//菜单
void menu() {
system("clear");
cout<<"*********************************************"<<endl;
cout<<"* 基本命令"<<endl;
cout<<"* 1.tanghan@pwd:显示当前所在目录的路径名"<<endl;
cout<<"* 2.tanghan@list <目录名>:列出指定目录名中的所有目录及文件"<<endl;
cout<<"* 3.tanghan@modifydir <目录名或路径>:改变当前工作目录"<<endl;
cout<<"* 4.tanghan@makedir<目录名>:新建目录"<<endl;
cout<<"* 5.tanghan@deldir<目录名> :删除目录"<<endl;
cout<<"* 6.tanghan@exit:退出程序"<<endl;
cout<<"* 拓展命令"<<endl;
cout<<"* 7.tanghan@rename <旧文件名> <新文件名>:重命名一个文件或目录"<<endl;
cout<<"* 8.tanghan@copy <已存在的文件名> <副本文件名或路径>:复制一个已存在的文件"<<endl;
cout<<"* 9.tanghan@date:显示当前日期"<<endl;
cout<<"*********************************************"<<endl;
cout<<endl;
}
int main() {
menu();
string s;
while(1) {
cout<<"请输入你的指令:";
cin>>s;
//显示当前所在目录的路径名
if(s=="tanghan@pwd"){
menu();
mypwd();
}
//列出指定目录名中的所有目录及文件
else if(s=="tanghan@list") {
menu();
cout<<"请输入指定一个目录:";
string dir;
cin>>dir;
if(!mylist(dir)) {
cout<<"目录打开失败或不存在!"<<endl;
}
}
//改变当前工作目录
else if(s=="tanghan@modifydir") {
menu();
cout<<"请输入指定一个目录:";
string path;
cin>>path;
if(!mycd(path)) {
cout<<"目录打开失败或不存在!"<<endl;
} else {
cout<<"当前工作目录为 "<<path<<endl;
}
}
//新建目录
else if(s=="tanghan@makedir") {
menu();
cout<<"请输入一个新的目录名:";
string dir;
cin>>dir;
if(!mymkdir(dir)) {
cout<<"创建目录失败!"<<endl;
} else {
cout<<"创建目录成功!"<<endl;
}
}
//删除目录
else if(s=="tanghan@deldir") {
menu();
cout<<"请输入一个存在的目录名:";
string dir;
cin>>dir;
if(!myrmdir(dir)) {
cout<<"目录不存在或删除失败!"<<endl;
} else {
cout<<"成功删除目录!"<<endl;
}
}
//退出程序
else if(s=="tanghan@exit") {
menu();
cout<<"再见!"<<endl;
return 0;
}
//重命名一个文件或目录
else if(s=="tanghan@rename") {
menu();
string lastname,newname;
cout<<"请输入需要修改的目录名或文件名:";
cin>>lastname;
cout<<"请输入新的目录名或文件名:";
cin>>newname;
if(!myrename(lastname,newname)) {
cout<<"重命名失败!"<<endl;
} else {
cout<<"重命名成功!"<<endl;
}
}
//显示当前日期
else if(s=="tanghan@date") {
menu();
date();
}
//创建/打开文件并写入
else if(s=="tanghan@creat") {
menu();
creatopen();
creatwrite();
}
//删除文件
else if(s=="tanghan@delete") {
menu();
cout<<"请输入一个存在的文件名:";
string dir;
cin>>dir;
if(!mydelete(dir)) {
cout<<"文件不存在或删除失败!"<<endl;
} else {
cout<<"成功删除文件!"<<endl;
}
}
//复制文件
else if(s=="tanghan@copy") {
menu();
string existname,newname;
cout<<"请输入需要复制的目录名或文件名:";
cin>>existname;
cout<<"请输入被复制的目录名或文件名:";
cin>>newname;
if(!mycopy(existname,newname)) {
cout<<"复制失败!"<<endl;
} else {
cout<<"复制成功!"<<endl;
}
}
//输入有误,重新输入
else {
menu();
cout<<"输入命令格式错误,请重新输入!"<<endl;
}
}
return 0;
}