内部模块化的命令行菜单小程序V2.0

1760阅读 0评论2017-05-07 suphgmh
分类:项目管理

“软件工程(C编码实践篇)”实验报告

实验三:内部模块化的命令行小程序V2.0


【郭昌明SA16225079+】

一、实验要求


  • 注意代码的业务逻辑和数据存储之间的分离,即将系统抽象为两个层级:菜单业务逻辑和菜单数据存储
  • 要求:1)遵守代码风格规范,参考借鉴代码设计规范的一些方法;2)代码的业务逻辑和数据存储使用不同的源文件实现,即应该有2个.c和一个.h作为接口文件。

二、实验步骤


1.创建项目文件夹lab3

$ cd shiyanlou_cs122
$ mkdir lab3
$ cd lab3 

2.设置vim格式

此步骤与实验二的vim设置步骤相同,不再赘述。

menu.c

#include  #include  #include "linklist.h" void help(); void pwd(); void ls(); void ps(); void date(); void author(); void code(); void quit(); #define CMD_MAX_LEN 128 #define DESC_LEN    1024 #define CMD_NUM     10 static tDataNode head[] = 
{
    {"help", "Show the help information.", help, &head[1]},
    {"pwd", "Print working directory.", pwd, &head[2]},
    {"ls", "List the file.", ls, &head[3]},
    {"ps", "List the Process.", ps, &head[4]},
    {"date", "Show the current date.", date, &head[5]},
    {"author", "Show the author information.", author, &head[6]},
    {"code", "Print the code.", code, &head[7]},
    {"quit", "Quit from the menu.", quit, NULL}
}; int main() { while(1)
    { char cmd[CMD_MAX_LEN]; printf("*******************\n"); printf("Snowball's MENU:\n"); printf("Please input a comand:\n"); scanf("%s", cmd);
        tDataNode *p = FindCmd(head,cmd); if(p == NULL)
        { printf("WRONG COMMAND!\n"); continue;
        } printf("%s - %s\n",p->cmd, p->desc); if(p->handler != NULL)
        {
            p->handler();
        }
    } return 0;
} void help() {
    ShowAllCmd(head);
} void pwd() { 
    system("pwd");
} void ls() {
    system("ls");
} void ps() {
    system("ps");
} void date() {
    system("date");
} void author() { printf("The code is written by Snowball Wang.\nCopyright Reserved.\n");
} void code() { char c;
    FILE *fp = NULL;
    fp = fopen("menu.c","r"); if(fp == NULL)
    { printf("Error: menu.c does not exist at all!");
    } while(fscanf(fp,"%c",&c) != EOF)
    { printf("%c",c);
    }
    fclose(fp);
    fp = NULL;
} void quit() { exit(0);
} 

linklist.h

typedef struct DataNode
{ char* cmd; char* desc; void (*handler)(); struct DataNode* next;
}tDataNode; tDataNode* FindCmd(tDataNode *head, char* cmd); int ShowAllCmd(tDataNode* head); 

linklist.c

#include  #include  #include "linklist.h" tDataNode* FindCmd(tDataNode* head, char* cmd) {
    tDataNode *p = head; if(head == NULL ||cmd == NULL)
    { return NULL;
    } while(p != NULL)
    { if(strcmp(p->cmd, cmd) == 0)
        { return p;
        }
        p = p->next;
    } return NULL;
} int ShowAllCmd(tDataNode* head) { printf("---------------------\n"); printf("Menu List:\n");
    tDataNode *p = head; while(p != NULL)
    { printf("%s -  %s\n", p->cmd, p->desc);
        p = p->next;
    } return 0;
} 

程序编写思想阐述 : 通过链接,实现对命令小程序的命令设计的模块化,如果需要在命令行小程序中继续添加命令,则只需修改链表,添加新的结点即可。删除命令反之亦然。由此,命令行小程序的扩展性得到了显著提高,这也是模块化思想的好处。

4.实验效果

实验效果1

实验效果2

三、课程总结


关于模块化(Modularity)的学习和理解,参照,总结如下:

代码设计中的一些常见方法:

  • 1.KISS原则(keep it simple&stupid) 一个函数或者方法只做一件事
  • 2.Using design to frame the code 设计与实现要保持一致
  • 3.Including pseudocode: 包含伪代码
  • 4.不要和陌生人说话原则
  • 5.合理利用Control structures、Data structures来简化代码 通过总结代码中的各类数据的规律,来定义合适的数据结构
  • 6.一定要有错误处理 20/80定律 前80%的代码只花了20%的时间,而剩下的20%的代码则花了其余的80%的时间,这80%的时间绝大部分是在进行错误处理

牢记一点:代码风格规范是程序员的基本素养!

四、实验收获


1.本次实验进一步加深了我对git的使用。我是在本地电脑完成的实验,没有使用实验楼环境。在git push的过程中,总是出现"could not resolve host"的原因。修改了很多次,终于解决了问题。

解决方案:

$ git push http://git.shiyanlou.com/[用户名]/shiyanlou_cs[课程名].git 

我出错的原因就在于没有在对应的链接后面加上.git,导致无法解析链接。

2.熟悉了模块化的编程思想。以前编程能够完成预定的目标即可,不回去进一步考虑到所写的程序的可拓展性、健壮性等需求。这次实验三让我体验了模块化编程的重要性以及必要性。

3.本次实验重温了链表的编程,进一步加深了我对孟宁老师上课说的程序=数据结构+算法的理解

上一篇:命令行菜单小程序V1.0
下一篇:用可重用的链表模块来实现命令行菜单小程序V2.5