实验三:内部模块化的命令行菜单小程序V2.0
实验要求(参照视频中的具体实验过程)
注意代码的业务逻辑和数据存储之间的分离,即将系统抽象为两个层级:菜单业务逻辑和菜单数据存储
要求:1)遵守代码风格规范,参考借鉴代码设计规范的一些方法;2)代码的业务逻辑和数据存储使用不同的源文件实现,即应该有2个.c和一个.h作为接口文件。
menu.c 源代码:
#include <stdio.h>
#include <stdlib.h>
#include <linklist.h>
int Help();
int Quit();
#define CMD_MAX_LEN 128
#define DESC_LEN 1024
#define CMD_NUM 10
static tDataNode head[] =
{
{"help", "this is help cmd!", Help, &head[1]},
{"version", "menu program v1.0", NULL, &head[2]}.
{"quit", "Quit from menu", Quit, NULL,}
};
main()
{
/*cmd line begins */
while(1)
{
char cmd[CMD_MAX_LEN];
printf("Input a cmd number > ");
scanf("%s", cmd);
tDataNode *p = FindCmd(head, cmd);
if(p == NULL)
{
printf("This is a wrong cmd!\n ")
continue;
}
printf("%s - %s\n", p->cmd, p->desc);
if(p->handler != NULL)
{
p->handler();
}
}
}
int Help()
{
printf("Menu List:\n");
tDataNode *p = head;
while(p != NULL)
{
printf("%s - %s\n", p->cmd, p->desc);
p = p->next;
}
return 0;
}
int Quit()
{
exit(0);
}
linklist.c源代码:
#include <stdio.h>
#include <stdlib.h>
#include <linklist.h>
DataNode * FindCmd(tDataNode * head, char * cmd)
{
if(head == NULL || cmd == NULL)
{
return NULL;
}
tDataNode *p = head;
while (p != NULL)
{
if(strcmp(p->cmd, cmd) == 0)
{
return p;
}
p = p->next;
}
return NULL;
}
int ShowAllCmd(tDataNode * head)
{
printf("Menu List:\n");
tDataNode *p = head;
while(p != NULL)
{
printf("%s - %s\n", p->cmd, p->desc);
p = p->next;
}
return 0;
}
linklist.h源代码:
typedef struct DataNode
{
char* cmd;
char* desc;
int (*handler)();
struct DataNode *next;
} tDataNode;
/* find a cmd in the linklist and return the datanode pointer */
tDataNode* FindCmd(tDataNode * head, char * cmd);
/*show all cmd in linklist */
int ShowAllCmd(tDataNode * head);
编译多个c文件:
Git 提交
心得体会:
#include :首先去系统目录中找头文件,如果没有在到当前目录下找。所以像标准的头文件 stdio.h、stdlib.h等用这个方法。
#include “xxx”:首先在当前目录下寻找,如果找不到,再到系统目录中寻找。 这个用于include自定义的头文件,让系统优先使用当前目录中定义的。
git commit -m 命令后面描述部分需要加引号。