帮助编写一个c语言程序 微型命令解释程序

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了帮助编写一个c语言程序 微型命令解释程序相关的知识,希望对你有一定的参考价值。

须具有下列5条命令
cdir(列出当前文件和目录)
ccopy文件1 文件2(拷贝文件)
cerase 文件名(删除文件)
Cdis (字符串)
Cend (退出微型命令解释程序)

一般地可以从标准输入中读取字符串

然后通过正则表达式或者手工匹配对字符串进行解析

首先解析指令

然后再解析指令的参数

最后根据指令和参数再通过相应操作系统提供的api来完成相关任务


下面是一个简单的c语言例子

解析的操作在各平台都是一样的

我这里以linux平台为基础做一个例子(该程序是可移植的)


首先定义命令操作的一些接口头文件(fos.h)

#ifndef _FOS_H
#define _FOS_H

#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>

#define BUF 2048
#define MAX_PATH 512

void show_dir(void);

int copy_file(char *from,char *to,mode_t mode);

int copy(char *file,char *old_path,char *to,mode_t mode,
        uid_t uid,gid_t gid);

int copy_dir(char *old_path,char *to);

int remove_file(char *filename);

int remove_dir(char *filename);

#endif


然后实现各接口(fos.c)

#include "fos.h"

#define JMP ((strcmp(dir->d_name,".") == 0) || (strcmp(dir->d_name,"..") == 0))

void show_dir(void)

    DIR *dirp;
    struct dirent *dir;

    dirp=opendir(".");
    if(dirp == NULL)
        return;

    while((dir=readdir(dirp)) != NULL)
        printf("%s\\n",dir->d_name);
    
    closedir(dirp);


int copy_file(char *from,char *to,mode_t mode)

    int in,out;
    char buf[BUF];
    size_t n;

    if((in=open(from,O_RDONLY)) == -1)
        return -1;

    if((out=open(to,O_CREAT|O_WRONLY,mode)) == -1)
    
        close(in);
        return -1;
    

    while((n=read(in,buf,sizeof(buf))) > 0)
        write(out,buf,n);

    close(in);
    close(out);

    if(n == -1)
        return -1;

    return 0;


int copy(char *file,char *old_path,char *to,mode_t mode,
        uid_t uid,gid_t gid)

    int in,out;
    char buf[BUF];
    size_t n;

    if((in=open(file,O_RDONLY)) == -1)
        return -1;
    if(chdir(to) == -1)
    
        close(in);
        return -1;
    

    if((out=open(file,O_CREAT|O_WRONLY,mode)) == -1)
    
        close(in);
        return -1;
    
    chown(file,uid,gid);

    while((n=read(in,buf,sizeof(buf))) > 0)
        write(out,buf,n);

    close(in);
    close(out);
    if(n == -1)
        return -1;

    if(chdir(old_path) == -1)
        return -1;

    return 0;


int copy_dir(char *old_path,char *to)

    DIR *dirp;
    struct dirent *dir;
    char buf[MAX_PATH];
    struct stat mode;
    char *current;
    char new_path[MAX_PATH];

    if((dirp=opendir(old_path)) == NULL)
        return -1;
    if(chdir(old_path) == -1)
    
        closedir(dirp);
        return -1;
    
    if((current=getcwd(NULL,0)) == NULL)
    
        closedir(dirp);
        return -1;
    

    while((dir=readdir(dirp)) != NULL)
    
        if(JMP)
            continue;

        if(stat(dir->d_name,&mode) == -1)
        
            perror(dir->d_name);
            continue;
        

        if(S_ISDIR(mode.st_mode))
        
            if(chdir(to) == -1)
                continue;
            if(mkdir(dir->d_name,mode.st_mode) == -1)
                continue;
            chown(dir->d_name,mode.st_uid,mode.st_gid);
            if(chdir(current) == -1)
                continue;
            snprintf(new_path,sizeof(new_path),"%s/%s",to,dir->d_name);
            if(copy_dir(dir->d_name,new_path) == -1)
                continue;
        
        else
        
            if(copy(dir->d_name,current,to,mode.st_mode,mode.st_uid,mode.st_gid) == -1)
                continue;
        
    

    free(current);
    closedir(dirp);
    if(chdir("..") == -1)
        return -1;

    return 0;


int remove_file(char *filename)

    struct stat buf;

    if(stat(filename,&buf) == -1)
        return -1;

    if(S_ISDIR(buf.st_mode))
        remove_dir(filename);
    else
        return remove(filename);


int remove_dir(char *filename)

    DIR *dirp;
    struct dirent *dir;
    struct stat buf;

    if(rmdir(filename) != -1)
        return 0;

    if((dirp=opendir(filename)) == NULL)
        return -1;

    chdir(filename);
    while((dir=readdir(dirp)) != NULL)
    
        if(JMP)
            continue;

        stat(dir->d_name,&buf);

        if(S_ISDIR(buf.st_mode))
            remove_dir(dir->d_name);
        else
            remove(dir->d_name);
    

    closedir(dirp);
    chdir("..");
    rmdir(filename);

    return 0;

接着我们就可以读入数据并解析命令行了

#include "fos.h"

#define SHOW_DIR 0
#define COPY_FILE 1
#define DELETE_FILE 2
#define SHOW_STR 3
#define EXIT 4
#define ERROR -1

#define TEST_CMD(c,n,s,f) \\
\\
    if(strncmp(cmd,c,n) == 0)\\
    \\
        cmd+=n;\\
        while(*cmd != ' ' && *cmd)\\
            ++cmd;\\
        if(*cmd == ' ')\\
        \\
            while(*cmd == ' ')\\
                ++cmd;\\
            snprintf(args,512,"%s",cmd);\\
            return s;\\
        \\
        if(f)\\
            return s;\\
    \\


int parse_cmd(char *cmd,char *args)

    TEST_CMD("cdir",4,SHOW_DIR,1);
    TEST_CMD("ccopy",5,COPY_FILE,0);
    TEST_CMD("cerase",6,DELETE_FILE,0);
    TEST_CMD("Cdis",4,SHOW_STR,0);
    TEST_CMD("Cend",4,EXIT,1);

    return ERROR;


int main(int argc,char **argv)

    char cmd[1024];
    char args[512];
    char *p;
    struct stat buf;
    size_t n;

    while(1)
    
        //memset(cmd,0,sizeof(cmd));

        printf(">");
        fflush(stdout);
        n=read(STDIN_FILENO,cmd,sizeof(cmd)-1);
        cmd[n-1]='\\0';
        //fread(cmd,sizeof(cmd)-1,1,stdin);

        switch(parse_cmd(cmd,args))
        
            case SHOW_DIR:
                show_dir();
                break;

            case COPY_FILE:
                p=strtok(args," ");
                stat(p,&buf);
                if(S_ISDIR(buf.st_mode))
                    copy_dir(p,strtok(NULL," "));
                else
                    copy_file(p,strtok(NULL," "),buf.st_mode);
                break;

            case DELETE_FILE:
                remove_file(args);
                break;

            case SHOW_STR:
                printf("%s\\n",args);
                break;

            case EXIT:
                goto end;
                break;

            default:
                printf("错误的指令!\\n");
        
    

end:
    printf("退出 . . .\\n");

    return 0;

这里我没有使用正则表达式来完成解析的工作

事实上我们也可以使用正则表达式来进行命令的解析

上面的例子只是一个简单的例子

要做到更加完善则需要添加更多的代码

但对于微型命令解析来说,基本的步骤和方法就是这样了

参考技术A #include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main()

char ins[256];
char cmd[256];
while(1)

printf("input order: ");
fflush(stdin);
scanf("%[^\n]", ins);
if(strncmp(ins, "cdir", 4) == 0)

system("dir");

else if(strncmp(ins, "ccopy", 5) == 0)

sprintf(cmd, "copy %s", (char*)ins + 5);
system(cmd);

else if(strncmp(ins, "cerase", 6) == 0)

sprintf(cmd, "del -f %s", (char*)ins + 6);
system(cmd);

else if(strncmp(ins, "cdis", 4) == 0)

printf("%s\n", ins + 4);

else if(strncmp(ins, "cend", 4) == 0)

exit(0);

else

printf("unknown order!\n");



return 0;


给出一个简单的实现。望采纳。
参考技术B 我可以给你做,题主付费吗?需要可加468317748 参考技术C 思路是⑴ 用静态数组或二维数组形式定义命令保留字表和shell命令字表。静态数组形式如下:static char * cst[ ]="ls"…" exit ";static char * scwt []="ls —l"…"exit";
⑵ 输入命令字gets(string);
⑶ 分离命令字strcspn();strncpy()
⑷ 比较命令字strcmp();
⑸ 执行shell命令system();

代码:
#include<string.h>
#include<process.h>
#include<stdio.h>
void main()
int i,num;
char a[10],b[50],c[50],d[50],e[50];
char sjs[5][20]="dir","copy","erase","dis","end";
while(1) printf("***********************\n");
printf("* dir:文件目录清单*\n");
printf("* copy:复制文件*\n");
printf("* erase:删除文件*\n");
printf("* dis:显示字符串*\n");
printf("* end:退出微命令*\n");
printf("*********************\n");
printf("***********************\n");
printf("Please input b:\n"); scanf("%s",&a);
for(i=0;i<5;i++)
if(!strcmp(a,sjs[i]))
num=i;
break;
num=7;



strcpy(b,"");
strcpy(c,""); strcpy(d,"");
switch(num)
case 0: strcpy(b,"dir");
break;
case 1:
printf("输入您所需的文件名:");
scanf("%s",&e);
printf("输入新复制文件名:");
scanf("%s",&c);
strcat(b,"copy ");
strcat(b,e);
strcat(b," ");
strcat(b,c);

break;
case 2:
printf("输入要删除的文件名:");
scanf("%s",d);
strcat(b,"del ");
strcat(b,d);
break;
case 3: printf("请输入字符串:");
scanf("%s",&e); strcat(b," ");
printf("输入的字符串为:%s",e); break;
case 4: printf("退出!!!!\n");

exit(0);

default: printf("错误输入,重新输入\n");



if(num>=0&&num<=4)
printf("%s\n",b);
system(b);



实验一 命令解释程序

 实验一、命令解释程序实验

一、实验目的

(1)掌握命令解释程序的原理;

(2)掌握简单的DOS调用方法;

(3)掌握C语言编程初步。

 

二、实验内容和要求

编写类似于DOS,UNIX的命令行解释程序

(1)自行定义系统提示符

(2)自定义命令集(8-10个)

(3)用户输入HELP以查找命令的帮助

(4)列出命令的功能,区分内部还是外部命令

(5)用户输入QUIT退出

(6)内部命令有dir, cd, md, rd, cls, date, time, ren, copy等。

 

三、实验方法、步骤及结果测试

 

  1. 1.     源程序名:压缩包文件(rarzip)中源程序名0311.c

      可执行程序名:0311.exe

  1. 2.     原理分析及流程图  

      用文件读写的方式将命令及命令作用存入结构体数组

      命令解释程序的原理:

        命令解释程序的主要功能是:

          接受和执行一条用户从键盘输入的命令,它通常保存一张命令名字(动词)表,其中记录着所有操作命令及其处理程序的入口地址或有关信息。

        命令解释程序实现的两种方式 :

          一种是它自身包含了命令的执行代码;

          另一种是由专门的“系统程序” 实现,自身不含命令处理代码,也不进行处理,仅仅把这条命令对应的命令文件装入内存执行。

  1. 3.     主要程序段及其解释:
#include <stdio.h>
#include <string.h>

struct
{
    char character[50];//命令字符
    char explain[200];//命令解释
    int category;//命令分类 1-内部命令 0-外部命令
}typedef command;

int count = 0;
command cmd[30];

void Init()//读取文件
{        
    FILE *fp;
    if((fp=fopen("cmd.txt","a+"))!=NULL)
    {
        while(!feof(fp)&&fgetc(fp)!=EOF)
        {
            fseek(fp,-1L,SEEK_CUR);
            fscanf(fp,"%s%s%d",&cmd[count].character,&cmd[count].explain,&cmd[count].category);
            count++;
        }
    }else
        printf("fail to open");
    fclose(fp);

}
void Title()//打印标题
{
    printf("Microsoft Windows [版本 10.0.10586]\n");
    printf("(c) 2015 Microsoft Corporation。保留所有权利。\n");

}
void Processing(char *ch)//处理函数
{
    int i = 0;
    char key;
    if(!strcmp(ch, "help"))
    {
        for(i = 0; i < count; i++)
        {
            printf("%s\t", cmd[i].character);
            printf("%s\n", cmd[i].explain);
        }
    }else
    {
        for(i = 0; i < count; i++)
        {
            if(!strcmp(ch, cmd[i].character))
            {
                if(cmd[i].category == 1)
                    printf("%s为内部命令\n", cmd[i].character);
                else
                    printf("%s为外部命令\n", cmd[i].character);
                printf("作用是:%s\n", cmd[i].explain);
                getchar();//清除缓存
                printf("是否执行该命令(y/n):");
                scanf("%c", &key);
                if(key == y || key == Y)
                    system(cmd[i].character);
                break;
            }
        }
        if(i == count)
            printf("‘%s‘ 不是内部或外部命令,也不是可运行的程序\n或批处理文件。\n", ch);
    }
}

int main(void)
{
    char ch[30];
    char *p;
    Init();    
    Title();
    do
    {
        printf("\nC:\\>");
        scanf("%s", ch);
        p = strlwr(ch);//将大写字符转化为小写字符
        Processing(p);
    }while(strcmp(ch, "quit"));

    return 0;
}

 

  1. 4.     运行结果及分析

技术分享

技术分享

技术分享

技术分享

 技术分享

  实验结果与预期相符

四、实验总结

  1. 复习巩固了大一学习的c语言,对结构体用法,文件读写更为熟练
  2. 在读取文件时按一定格式读取,分别存储
  3. 在解决输入字符串的大小写转化过程中,查询资料学习到
    1. char *strupr(char *s) 将字符串s转换为大写形式
      说明:只转换s中出现的小写字母,不改变其它字符。返回指向s的指针。
    2. char *strlwr(char *s) 将字符串s转换为小写形式
      说明:只转换s中出现的大写字母,不改变其它字符。返回指向s的指针。
  4. 学习到在c语言中用system()函数执行dos命令

   

 

 

 

 

 

 

 

 

 

以上是关于帮助编写一个c语言程序 微型命令解释程序的主要内容,如果未能解决你的问题,请参考以下文章

操作系统-命令解释程序(拓展)

实验一 命令解释程序

命令解释程序的编写

用Microsoft Visual Stdio2015编写C语言的问题

cmd如何编译记事本中的代码

实验一 命令解释程序