当前位置: 首页 > news >正文

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、相关函数

  1. getline()
#include<stdio.h>ssize_tgetline(char**lineptr,size_t*n,FILE*stream);

从文件流stream读取一行数据,结果保存到*lineptr中,结尾包括空字符和换行符。

  1. parsecmd()
voidparsecmd(char*s)

解析命令行内容,主要通过函数stripcmd/getcmdindex实现。

  • stripcmd
intstripcmd(char*s,charcmds[][256])

借助库函数strtok,通过空格将命令行s中各个参数分隔开,提取出参数,然后存储到二维数组**char cmds[256]**中,

  • getcmdindex
intgetcmdindex(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];intargc=0;intindex=-1;argc=stripcmd(s,cmd);//printf("argc=%d\n",argc);index=getcmdindex(cmd[0]);if(index==-1){if(argc>0){cprintf(RED,"\tNo such commond \n");}return;}elseif(argc>0){cmdlist[index].callback(cmd,argc);}}UINT8hex2char(UINT8 ch){if((ch>='0')&&(ch<='9')){returnch-'0';}if((ch>='a')&&(ch<='f')){returnch-'a'+10;}if((ch>='A')&&(ch<='F')){returnch-'A'+10;}return(UINT8)0xff;}UCHARstringToByte(char*str){UCHAR bytes=0;if(strlen(str)==1){bytes=0<<4|hex2char(str[0]);}else{bytes=hex2char(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){inti=0;intlen=0;UCHAR buf[256]={0};if(argc<2){return;}for(i=1;i<argc;i++){buf[i-1]=stringToByte(argv[i]);}cprintf(GREEN,"\n buf:");for(i=0;i<argc-1;i++){cprintf(GREEN,"%02x ",buf[i]);}putchar('\n');}voidtest(charargv[][256],intargc){inti=0;for(i=0;i<argc;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){inti=0;for(i=0;i<sizeof(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;intret=0;size_tlen_line=0;showsysinfo();while(1){fflush(stdin);cprintf(D_GREEN_H,DEV_NAME"# ");ret=getline(&line,&len_line,stdin);if(ret==-1){break;}parsecmd(line);free(line);line=NULL;}return0;}

三、测试

1. help

2. test

3. send

4. exit

http://www.jsqmd.com/news/668901/

相关文章:

  • 正点原子达芬奇FPGA运动目标检测仿真代码:ov5640配置与数据输出,RGB转YUV,帧差、...
  • 浅析golang中的垃圾回收机制(GC)
  • 为什么顶尖AI实验室已暂停通用模型迭代?SITS2026圆桌闭门纪要首度外泄:AGI自主演化证据链+人类控制窗口期剩余≤11个月
  • 告别ImageMagick卡顿!试试这个更快的图片处理神器GraphicsMagick,附CentOS 7保姆级安装教程
  • 贵阳找工作怎么办?毕业季困局与破局:贵阳应届生的求职地图 - 精选优质企业推荐官
  • golang如何调用Twilio语音短信API_golang Twilio语音短信API调用实战
  • CSS如何实现跨容器的连线效果_利用绝对定位的线条结合宽高与旋转角度连接两个节点
  • 【项目实战】基于语言大模型的智能居家养老健康守护系统后端:情感陪伴 Agent 开发与全功能测试报告
  • [K8s/本地存储] Kubernetes 本地存储进化史:从 hostPath 到 local-path-provisioner
  • 定义层间接触
  • 汽车零部件企业ERP数字化转型实践:基于SAP Business One的落地经验
  • 贵阳招聘市场风向标:2026年最值得关注的12家公司与岗位机会分析 - 精选优质企业推荐官
  • 告别RPM/Yum:为什么我选择用tar.xz源码包在Linux上部署MySQL 8.0?
  • 2026年沈阳婚纱照排名大揭秘,哪家才是你的心头好?
  • 多客圈子论坛代码审计(PHP代码审计)
  • 【AGI政策制定黄金72小时】:从奇点大会技术共识到地方条例起草的实战操作手册
  • 欠驱动无人船AUV二维路径跟踪控制(反步控制+LOS制导)MATLAB仿真
  • C++:全景目录
  • 贵阳招聘市场2026年全景盘点:10大竞品对比与求职指南 - 精选优质企业推荐官
  • 【仅限前200名技术决策者获取】:2026奇点大会AGI气候预测引擎API接口规范及部署手册(含实测减排误差<0.8%的基准测试数据)
  • 从CSP-J真题到算法实战:拆解‘鸡蛋硬度’问题的递归与动态规划双视角
  • 如何在Unity中5分钟内实现专业级3D高斯泼溅渲染
  • 2026创新项目实训-项目博客(三)
  • 嵌入式消费品商业开发需求导出与便捷调试
  • SpringBoot+Vue企业人事管理系统源码+论文
  • 5G手机第一次联网时,基站是怎么知道你在哪个方向的?聊聊PRACH Occasion与波束的‘暗号’映射
  • Substance 3D Painter Pt 2025 v11.0.1详细图文安装教程
  • 山东大学软件学院项目实训-创新实训-计科智伴(一)——个人博客(后端搭建)
  • 常识不是知识,而是推理操作系统:解密AGI底层常识架构的5层抽象模型与2个已被验证的轻量化嵌入方案
  • 第 4 篇 - Redis 数据类型总览:5 种核心类型