c语言实例|实现简单的命令行

张开发
2026/4/20 2:00:16 15 分钟阅读

分享文章

c语言实例|实现简单的命令行
嵌入式系统开发经常需要用到命令行功能比如uboot命令行。命令行可以增加程序运行的灵活性方便我们调试程序大幅提高我们开发效率。本文通过过一个简单的例子来教大家如何实现一个简单的命令行模块该模块可以很方便的移植到自己的c项目中。完整源码获取见文末。一、设计思想二、实现1、结构体模块支持的命令相关信息我们用结构体 struct _cmdnum来维护。typedefvoid(*CMDFUNC)(char[][256],intargc);typedefstruct_cmdnum{char*cmd;intindex;intparamcount;CMDFUNC callback;char*info;}CMDNUM,*PCMDNUM;成员含义char *cmd命令名字int index命令下标int paramcount命令参数个数CMDFUNC callback命令对应回调函数2、支持的命令本问例子中加了4个命令功能参数个数回调函数help显示所有命令信息0showhelp():–:–exit退出当前进程test打印所有参数信息测试用3test()send将输入的16进制字符串转换成16进制整形数并存入数组中MAX_PARAM_NUMsend()定义如下CMDNUM cmdlist[]{{help,1,0,showhelp},{exit,2,0,quit},{test,3,3,test},{send,4,MAX_PARAM_NUM,send},};3、相关函数getline()#includestdio.hssize_tgetline(char**lineptr,size_t*n,FILE*stream);从文件流stream读取一行数据结果保存到*lineptr中结尾包括空字符和换行符。parsecmd()voidparsecmd(char*s)解析命令行内容主要通过函数stripcmd/getcmdindex实现。stripcmdintstripcmd(char*s,charcmds[][256])借助库函数strtok通过空格将命令行s中各个参数分隔开提取出参数然后存储到二维数组**char cmds[256]**中getcmdindexintgetcmdindex(char*name)通过命令名字name遍历数组cmdlist[],并得到数组下标index。4、核心代码CMDNUM cmdlist[]{{help,1,0,showhelp,show all cmd info},{exit,2,0,quit,quit application},{test,3,3,test,[param...]print params},{send,3,MAX_PARAM_NUM,senddata,[xx...]converts data from sting to hex and store to buf},};voidparsecmd(char*s){charcmd[MAX_PARAM_NUM][256];intargc0;intindex-1;argcstripcmd(s,cmd);//printf(argc%d\n,argc);indexgetcmdindex(cmd[0]);if(index-1){if(argc0){cprintf(RED,\tNo such commond \n);}return;}elseif(argc0){cmdlist[index].callback(cmd,argc);}}UINT8hex2char(UINT8 ch){if((ch0)(ch9)){returnch-0;}if((cha)(chf)){returnch-a10;}if((chA)(chF)){returnch-A10;}return(UINT8)0xff;}UCHARstringToByte(char*str){UCHAR bytes0;if(strlen(str)1){bytes04|hex2char(str[0]);}else{byteshex2char(str[0])4|hex2char(str[1]);}returnbytes;}//7e 01 02 01 00 07 07 01 00 00 00 c6 51 2a 7evoidsenddata(charargv[][256],intargc){inti0;intlen0;UCHAR buf[256]{0};if(argc2){return;}for(i1;iargc;i){buf[i-1]stringToByte(argv[i]);}cprintf(GREEN,\n buf:);for(i0;iargc-1;i){cprintf(GREEN,%02x ,buf[i]);}putchar(\n);}voidtest(charargv[][256],intargc){inti0;for(i0;iargc;i){cprintf(YEL,\targv[%d]:%s\n,i,argv[i]);}return;}voidshowsysinfo(void){cprintf(D_GREEN_H,---------------yikoulinux cmdline demo-----------\n);}voidquit(charcmd[][256],intargc){cprintf(RED_H,exit to system \n);exit(0);}voidshowhelp(charcmd[][256],intargc){inti0;for(i0;isizeof(cmdlist)/sizeof(CMDNUM);i){cprintf(GREEN_H,\t%s,cmdlist[i].cmd);cprintf(YEL_H,\t%s\n,cmdlist[i].info);}return;}intmain(intargc,char*argv[]){char*line;intret0;size_tlen_line0;showsysinfo();while(1){fflush(stdin);cprintf(D_GREEN_H,DEV_NAME# );retgetline(line,len_line,stdin);if(ret-1){break;}parsecmd(line);free(line);lineNULL;}return0;}三、测试1. help2. test3. send4. exit

更多文章