帮助编写一个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;
这里我没有使用正则表达式来完成解析的工作
事实上我们也可以使用正则表达式来进行命令的解析
上面的例子只是一个简单的例子
要做到更加完善则需要添加更多的代码
但对于微型命令解析来说,基本的步骤和方法就是这样了
#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. 源程序名:压缩包文件(rar或zip)中源程序名0311.c
可执行程序名:0311.exe
- 2. 原理分析及流程图
用文件读写的方式将命令及命令作用存入结构体数组
命令解释程序的原理:
命令解释程序的主要功能是:
接受和执行一条用户从键盘输入的命令,它通常保存一张命令名字(动词)表,其中记录着所有操作命令及其处理程序的入口地址或有关信息。
命令解释程序实现的两种方式 :
一种是它自身包含了命令的执行代码;
另一种是由专门的“系统程序” 实现,自身不含命令处理代码,也不进行处理,仅仅把这条命令对应的命令文件装入内存执行。
- 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; }
- 4. 运行结果及分析
实验结果与预期相符
四、实验总结
- 复习巩固了大一学习的c语言,对结构体用法,文件读写更为熟练
- 在读取文件时按一定格式读取,分别存储
- 在解决输入字符串的大小写转化过程中,查询资料学习到
- char *strupr(char *s) 将字符串s转换为大写形式
说明:只转换s中出现的小写字母,不改变其它字符。返回指向s的指针。
- char *strlwr(char *s) 将字符串s转换为小写形式
说明:只转换s中出现的大写字母,不改变其它字符。返回指向s的指针。
- 学习到在c语言中用system()函数执行dos命令
以上是关于帮助编写一个c语言程序 微型命令解释程序的主要内容,如果未能解决你的问题,请参考以下文章