帮助编写一个c语言程序 微型命令解释程序
一般地可以从标准输入中读取字符串
然后通过正则表达式或者手工匹配对字符串进行解析
首先解析指令
然后再解析指令的参数
最后根据指令和参数再通过相应操作系统提供的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;
}
这里我没有使用正则表达式来完成解析的工作
事实上我们也可以使用正则表达式来进行命令的解析
上面的例子只是一个简单的例子
要做到更加完善则需要添加更多的代码
但对于微型命令解析来说,基本的步骤和方法就是这样了