在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. 主界面

在Linux环境下模拟实现命令解释器--C++_第1张图片

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

在这里插入图片描述

  1. 改变当前工作目录

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

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

在这里插入图片描述

  1. 新建目录

在这里插入图片描述

  1. 删除目录

在Linux环境下模拟实现命令解释器--C++_第2张图片

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

在Linux环境下模拟实现命令解释器--C++_第3张图片在Linux环境下模拟实现命令解释器--C++_第4张图片
在这里插入图片描述

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

在这里插入图片描述
在Linux环境下模拟实现命令解释器--C++_第5张图片

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

在这里插入图片描述

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

代码

#include 
#include 
#include  //mypwd
#include 
#include 
#include  //mylist
#include 
#include 
#include 
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 将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;
}

在Linux环境下模拟实现命令解释器--C++_第6张图片

你可能感兴趣的:(Linux,linux)