网易云ID:Nerd2dian0
源码:https://github.com/Nerd2dian0/Youcan/tree/master/lab6
实验要求:
- 为menu子系统设计接口,并写用户范例代码来实现原来的功能;
- 使用make和make clean来编译程序和清理自动生成的文件;
- 使menu子系统支持带参数的复杂命令,并在用户范例代码中自定义一个带参数的复杂命令;
- 可以使用getopt函数获取命令行参数。
实验过程:
实验楼克隆
实验结果演示:
实验代码(主要部分)
menu子系统设计接口:
int MenuConfig(char *cmd, char *desc, void (*handler)(int argc, char *argv[]));
//将具体的命令加入链表
int ExecuteMenu();
int Help(int argc, char **argv);
int Quit(int argc, char **argv);
makefile:
#
# Makefile for Menu Program
#
CC_PTHREAD_FLAG = -lpthread
CC_FLAGS = -c
CC_OUTPUT_FLAGS = -o
CC = gcc
RM = -rm
RM_FLAGS = -f
SRC = linkTable.c menu.c test.c
TARGET = test
OBJS = linkTable.o menu.o test.o
all: $(OBJS)
$(CC) $(CC_OUTPUT_FLAGS) $(TARGET) $(OBJS)
.c.o:
$(CC) $(CC_FLAGS) $<
clean:
$(RM) $(RM_FLAGS) $(OBJS) $(TARGET) *.bak
menu.c程序修改部分,实现自主添加命令和命令内容
int MenuConfig(char *cmd, char *desc, void (*handler)(int argc, char *argv[]))
{
if(head == NULL)
{
head = CreateLinkTable();
tDataNode *pNode = (tDataNode*) malloc(sizeof(tDataNode));
pNode->cmd = "help";
pNode->desc = "List all command in this program";
pNode->handler = Help;
AddLinkTableNode(head,(tLinkTableNode *)pNode);
}
tDataNode* pNode=(tDataNode*)malloc(sizeof(tDataNode));
pNode->cmd=cmd;
pNode->desc=desc;
pNode->handler=handler;
AddLinkTableNode(head,(tLinkTableNode *)pNode);
return 0;
}
int ExecuteMenu()
{
while(1)
{
int argc = 0;
char *argv[CMD_MAX_ARGV_NUM];
char cmd[CMD_MAX_LEN];
char *pcmd = NULL;
printf("Input a cmd number > ");
/*scanf("%s", cmd);*/
pcmd = fgets(cmd, CMD_MAX_LEN, stdin);
if(pcmd == NULL)
{
continue;
}
/* convert cmd to argc/argv */
pcmd = strtok(pcmd, " ");
while(pcmd != NULL && argc < CMD_MAX_ARGV_NUM)
{
argv[argc] = pcmd;
argc++;
pcmd = strtok(NULL, " ");
}
if(argc == 1)
{
int len = strlen(argv[0]);
*(argv[0] + len - 1) = '\0';
}
tDataNode *p = (tDataNode*)SearchLinkTableNode(head, SearchCondition, (void*)argv[0]);
if(p == NULL)
{
printf("This is a wrong cmd!\n");
continue;
}
if(p->handler != NULL)
{
p->handler(argc, argv);
}
}
return 0;
}
menu.h接口函数
//增添命令函数
int MenuConfig(char *cmd, char *desc, void (*handler)(int argc, char *argv[]));
//将具体的命令加入链表
int ExecuteMenu();
int Help(int argc, char **argv);
int Quit(int argc, char **argv);
getopt函数获取命令行参数
int Info(int argc, char** argv)
{
opterr = 0;
int oc;
while((oc = getopt(argc, argv, "nv")) != -1)
{
switch(oc)
{
case 'n':
printf("The author name is Nerd2dian0.\n");
break;
case 'v':
printf("The version is 1.01.\n");
break;
}
}
optind = 0; //如果没有这句,循环不在有用。
return 0;
}
实验总结:完成一个命令行的接口函数,通过test.c可以自己输入想要的命令到链表中。学习
使用make和make clean来编译程序和清理自动生成的文件;学习
使用getopt函数获取命令行参数。受益匪浅!!