在Linux环境下模拟实现命令解释器--C++

本次课程设计使用C++语言,在Linux发行版系统Ubuntu下编译运行。

在Linux环境下模拟实现简单命令解释器
实现的功能:

  1. 定义 mypwd 显示当前所在目录的路径名
  2. 定义 mylist 列出指定目录名中的所有目录及文件
  3. 定义 mycd 改变当前工作目录
  4. 定义 mymkdir 新建目录
  5. 定义 myrmdir 删除目录
  6. 定义 myexit 退出命令解释程序
  7. 定义 myrename <旧文件名> <新文件名> 重命名一个文件或目录
  8. 定义 mycopy <已存在的文件名> <副本文件名或路径> 复制一个已存在的文件
  9. 定义 myfind <目录> -name <待查找的文件名>
    在指定的目录及其子目录中查找指定的文件(输入文件名),并输出查找到的文件的绝对路径。

运行截图

  1. 主界面

在这里插入图片描述

  1. 显示当前所在目录的路径名

在这里插入图片描述

  1. 改变当前工作目录

在这里插入图片描述
在这里插入图片描述

  1. 列出指定目录中的所有目录及文件

在这里插入图片描述

  1. 新建目录

在这里插入图片描述

  1. 删除目录

在这里插入图片描述

  1. 重命名一个文件或目录

在这里插入图片描述在这里插入图片描述
在这里插入图片描述

  1. 复制一个已存在的文件

在这里插入图片描述
在这里插入图片描述

  1. 在指定的目录及其子目录中查找指定的文件(输入文件名),并输出查找到的文件的绝对路径。

在这里插入图片描述

  1. 退出系统
    在这里插入图片描述

代码

#include <iostream>
#include <stdio.h>
#include <unistd.h> //mypwd
#include <sstream>
#include <string.h>
#include <dirent.h> //mylist
#include <sys/types.h>
#include <sys/stat.h>
#include <ftw.h>
using namespace std;

string str;            //输入的命令
string mingling[1000]; //保存命令
int i;                 //命令长度

// mypwd --- pwd 显示当前所在目录的路径名
void mypwd()
{
  char mypwd[100];
  getcwd(mypwd, sizeof(mypwd));
  // getcwd()会将当前工作目录的绝对路径复制到参数mypwd所指的内存空间中
  cout << mypwd << endl;
}

// mylsit ---list 列出指定目录名中的所有目录及文件
void mylist()
{
  //判断命令长度
  if (i == 1)
  {
    cout << "mylist : 在后面缺少了要操作的目录" << endl;
  }
  else if (i == 2)
  {
    char temp[80];
    strcpy(temp, mingling[1].c_str()); //string转char
    DIR *dir = NULL;
    //opendir()用来打开参数name 指定的目录, 并返回DIR*形态的目录流, 和open()类似, 接下来对目录的读取和搜索都要使用此返回值.
    struct dirent *end;
    int j = 0; //逢6换行
    // 通过目录名,调用opendir()打开目录流
    if ((dir = opendir(temp)) != NULL)
    {
      /* code */
      // 调用readdir()函数读取目录,返回dirent*数据结构
      while (end = readdir(dir))
      {
        j++;
        /* code */
        // 将d_name(目录名/文件名)输出
        if (strcmp(end->d_name, "..") != 0 && strcmp(end->d_name, ".") != 0)
        {
          cout << end->d_name << "   ";
        }

        if (j % 10 == 0)
        {
          cout << endl;
        }
      }
      cout << endl;
    }
    else
    {
      /* code */
      cout << "没有这个文件或目录" << endl;
    }

    closedir(dir); //关闭流
  }
}

// mycd --- cd 改变当前工作目录
void mycd()
{
  if (i > 2)
  {
    cout << "-bash : cd : 参数太多" << endl;
  }
  else
  {
    char temp[200];  //保存当前目录
    char temp1[200]; //临时目录
    getcwd(temp, sizeof(temp));
    //如果单纯只有cd命令,返回上一个路径
    //格式为cd *** ,目录进入到
    if (i == 1)
    {
      /* code */
      char *index = strrchr(temp, '/');   //获取字符在指定字符串中从右面开始的第一次出现的位置index - temp
      strncpy(temp1, temp, index - temp); //strncpy()将 temp 中从第0个字符开始复制index - temp个字符给 temp1
      int result = chdir(temp1);          //改变当前目录路径
      if (result != 0)
      {
        printf("没有这个文件或目录\n");
      }
    }
    if (i == 2) //判断目录是否存在
    {
      DIR *dir = NULL;
      //拼接目录
      strcat(temp, "/");
      strcat(temp, mingling[1].c_str());
      // 通过目录名,调用opendir()打开目录流
      if ((dir = opendir(temp)) != NULL)
      {
        chdir(temp); //存在该目录,改变为此目录
      }
      else
      {
        /* code */
        cout << "-bash : cd : " << mingling[1] << " : 没有那个文件或目录" << endl;
      }

      closedir(dir); //关闭目录流
    }
  }
}

// mymkdir --- mkdir 新建目录
void mymkdir()
{
  int index = 0;
  /* code */
  index = mkdir(mingling[1].c_str(), 0777);

  if (index != 0)
  {
    printf("无法创建目录“%s”:文件已存在\n", mingling[1].c_str());
  }
}

// myrmdir  --- rmdir 删除目录
void myrmdir()
{
  int index = 0;
  /* code */
  index = rmdir(mingling[1].c_str());
  if (index != 0)
  {
    printf("删除“%s”失败:没有那个目录或目录不为空\n", mingling[1].c_str());
  }
}

// myrename --- rename 重命名一个文件或目录
void myrename()
{
  int index = 0;
  index = rename(mingling[1].c_str(), mingling[2].c_str());
  if (index != 0)
  {
    printf("无法获取“%s”的文件状态:没有那个文件和目录\n", mingling[1].c_str());
  }
}

// mycopy --- copy <已存在的文件名> <副本文件名或路径>  复制一个已存在的文件
void mycopy()
{
  if (i > 3)
  {
    cout << "-bash : mycopy : 参数太多" << endl;
  }
  if (i == 1 || i == 2)
  {
    cout << "mycopy : 在后面缺少了要操作的目录或文件" << endl;
  }
  else if (i == 3)
  {
    FILE *fp = NULL;  //源文件
    FILE *fp1 = NULL; //复制文件
    char temp[200];   //复制生成文件的目录路径
    //判断路径
    DIR *dir = NULL;
    strcpy(temp, mingling[2].c_str());
    fp = fopen(mingling[1].c_str(), "r");
    //如果第二个字段是路径
    if ((dir = opendir(temp)) != NULL)
    {
      chdir(temp);                           //存在该目录,改变为此目录
      fp1 = fopen(mingling[1].c_str(), "a"); //路径
    }
    else
    {
      /* code */
      //copy <已存在的文件名> <副本文件名>
      fp1 = fopen(mingling[2].c_str(), "a"); //副本文件名
    }
    char buff[255];
    while (!feof(fp)) //判断文件内容是否为空
    {
      /* code */
      fgets(buff, 255, fp); //读取文件
      fputs(buff, fp1);     //写入文件
    }
    fclose(fp); //关闭文件
    fclose(fp1);
  }
}

// myfind --- 具有 find <目录> -name <待查找的文件名>    在指定的目录及其子目录中查找指定的文件(输入文件名),并输出查找到的文件的绝对路径。
int fn(const char *file, const struct stat *sb, int flag)
{
  string temp1;      //存放绝对路径
  if (flag == FTW_F) //是文件
  {
    temp1 = file;
    char temp2[100]; //存放文件名
    strcpy(temp2, temp1.c_str());
    char *index = strrchr(temp2, '/'); //获取字符在指定字符串中从右面开始的第一次出现的位置index - temp
    //判断待查找的文件名存在,输出绝对路径
    if (strcmp(mingling[3].c_str(), temp1.substr(index - temp2 + 1, temp1.size()).c_str()) == 0)
    {
      cout << file << endl;
    }
  }
  return 0;
}
void myfind()
{
  //判断目录是否存在
  DIR *dir = NULL;
  if (i != 4)
  {
    cout << "命令配套不完整" << endl;
    return;
  }
  if ((dir = opendir(mingling[1].c_str())) == NULL)
  {
    cout << "-bash : myfind : " << mingling[1] << " : 没有那个文件或目录" << endl;
  }
  else
  {
    /* code */
    ftw(mingling[1].c_str(), fn, 500);
  }
}

//所完成的命令模拟
void menu()
{
  cout << endl;
  cout << " ****在Linux环境下模拟实现简单命令解释器****" << endl;
  cout << " 定义 mypwd  显示当前所在目录的路径名" << endl;
  cout << " 定义 mylist  列出指定目录名中的所有目录及文件" << endl;
  cout << " 定义 mycd  改变当前工作目录" << endl;
  cout << " 定义 mymkdir  新建目录" << endl;
  cout << " 定义 myrmdir  删除目录" << endl;
  cout << " 定义 myexit   退出命令解释程序" << endl;
  cout << " 定义 myrename <旧文件名> <新文件名>            重命名一个文件或目录" << endl;
  cout << " 定义 mycopy <已存在的文件名> <副本文件名或路径>  复制一个已存在的文件" << endl;
  cout << " 定义 myfind <目录> -name <待查找的文件名>       在指定的目录及其子目录中查找指定的文件(输入文件名),并输出查找到的文件的绝对路径。" << endl;
  cout << " ****************************************" << endl
       << endl;
}

//输入命令
void input()
{
  //模拟器标签
  char local[100] = " ~ ";
  char temp11[100];
  getcwd(temp11, sizeof(temp11));
  strcat(local, temp11);
  strcat(local, " > ");
  cout << local;
  getline(cin, str);
  //解析命令
  istringstream is(str); //头文件#include<sstream> 将string字符串按空格分开并分别保存
  string temp;           //临时变量
  for (i = 0; is >> temp; i++)
  {
    mingling[i] = temp;
  }
}

int main()
{
  menu();

  input();
  for (;;) //判断命令是否退出
  {
    if (strcmp(mingling[0].c_str(), "mypwd") == 0)
    {
      mypwd();
    }
    else if (strcmp(mingling[0].c_str(), "mylist") == 0)
    {
      mylist();
    }
    else if (strcmp(mingling[0].c_str(), "mycd") == 0)
    {
      mycd();
    }
    else if (strcmp(mingling[0].c_str(), "mymkdir") == 0)
    {
      mymkdir();
    }
    else if (strcmp(mingling[0].c_str(), "myrmdir") == 0)
    {
      myrmdir();
    }
    else if (strcmp(mingling[0].c_str(), "myexit") == 0)
    {
      _exit(0);
    }
    else if (strcmp(mingling[0].c_str(), "myrename") == 0)
    {
      myrename();
    }
    else if (strcmp(mingling[0].c_str(), "mycopy") == 0)
    {
      mycopy();
    }
    else if (strcmp(mingling[0].c_str(), "myfind") == 0)
    {
      myfind();
    }
    else
    {
      cout << "命令出错" << endl;
    }
    memset(mingling, 0, 200); //清除string数组
    input();
  }
  return 0;
}

在这里插入图片描述

  • 12
    点赞
  • 71
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 15
    评论
评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

sail Jamie

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

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

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

打赏作者

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

抵扣说明:

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

余额充值