今天的课题仅适合初入嵌入式系统的新手们(包含我自己,哈哈),老司机们可以跳过,当然也可以多多的提建议啊。
在嵌入式系统中,由于我们经常使用的命令行的模式,所以不能想windows下面那多的选择选项,那么就需要在执行命令的时候明确输入要定义的选项,也就是说程序要分析带入的参数。
那么有的朋友就会问了,那我就一点一点的分析就可以了啊,刚开始我也是这么做的,后来发现,太麻烦了如测试通讯的时候,要检测波特率,那么要输入-b 115200 ,那么还要考虑 -b115200这样行不行,我想默认波特率是115200,不用输入行不行,弄的有点乱。
一次碰巧的机会,接触到了getopt函数,终于到正题了啊,板凳摆好,好好听啊,嘿嘿。
getopt也可以使用三种方式
getopt、getopt_long,getopt_only
那么这三个有什么区别呢?
getopt只能接收短字符的分析,如-d,-b ,getopt_only则只能接收长参数如–h,–b,那么getopt_long就是长短参数都可以识别,在这里我仅对getopt和getopt_long进行举例分析。
1、getopt
对于这个函数使用的时候我们要包含头文件 <getopt.h>
例子如下:
/*forlinx serial port test*/
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <pthread.h>
#include <getopt.h>
#include <time.h>
// help 显示内容
static void print_usage(const char *pname)
{
printf("Usage: %s -d devname -b baudrate -s string "
"\nExample : %s -d /dev/ttymxc2 [-b 115200 -s forlinxsendata]"
"\n\t -d devname can list in /dev"
"\n\t -b baudrate ,list in doc,default is 115200"
"\n\t -s string ,the string for sending\n",
pname,pname
);
}
int main(int argc, char **argv)
{
//signal(SIGINT,SignHandler);
int next_option;
//执行获得参数,
printf("param is 'hd:b:s:t:'\n\n");
while((next_option = getopt(argc,argv,"hdbst")) !=-1)
{
//next_option = getopt(argc,argv,"hd:b:s:t:");
printf("getopt :\t ret=%c\t,optarg=%s\t,optind=%d\t,argv[optind]=%s\n",next_option,optarg,optind,argv[optind]);
switch (next_option)
{
case 'h':
print_usage(argv[0]);
break;
case 'd':
printf("printf input devices=%s\n",optarg);
break;
case 'b':
printf("printf baudrate here is %s\n",optarg);
//speedflag=1;
break;
case 's':
printf("printf string here %s\n",optarg);
break;
case 't':
printf("printf time here %s\n",optarg);
break;
case -1://解析完所有参数完成
printf("here param is finished\n");
break;
case '?':
print_usage(argv[0]);
exit(1);
default:
print_usage(argv[0]);
exit(1);
}
}//while(next_option != -1);
}
执行效果如下:
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$ ./getopt
param is 'hd:b:s:t:'
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$ ./getopt -h
param is 'hd:b:s:t:'
getopt : ret=h ,optarg=(null) ,optind=2 ,argv[optind]=(null)
Usage: ./getopt -d devname -b baudrate -s string
Example : ./getopt -d /dev/ttymxc2 [-b 115200 -s forlinxsendata]
-d devname can list in /dev
-b baudrate ,list in doc,default is 115200
-s string ,the string for sending
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$ ./getopt -d /dev/ttymxc2 -b 115200 -s www.baidu.com -t 12
param is 'hd:b:s:t:'
getopt : ret=d ,optarg=(null) ,optind=2 ,argv[optind]=/dev/ttymxc2
printf input devices=(null)
getopt : ret=b ,optarg=(null) ,optind=4 ,argv[optind]=115200
printf baudrate here is (null)
getopt : ret=s ,optarg=(null) ,optind=6 ,argv[optind]=www.baidu.com
printf string here (null)
getopt : ret=t ,optarg=(null) ,optind=8 ,argv[optind]=12
printf time here (null)
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$
2、getopt_long
这个稍微复杂一点,函数定义如下:
int getopt_long(int argc, char * const argv[], const char *optstring, const struct option *longopts, int longindex);
charoptstring = “x🅱️:d:j”;
单个字符j 表示选项j没有参数 格式:-j即可,不加参数
单字符加冒号x: 表示选项x有且必须加参数 格式:-x 100或-x100
单字符加2冒号b:: 表示选项b可以有,也可以无 仅有的格式:-b200
longopts是一个结构的数据,如下:
const struct option long_opt[] = {
{“devices”,1,NULL,‘d’},
{“baudrate”,1,NULL,‘b’},
{“string”,1,NULL,‘s’},
{“times”,1,NULL,‘t’},
{NULL,0,NULL,0},
};
下面我们举一个应用的例子:
/*forlinx serial port test*/
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <signal.h>
#include <pthread.h>
#include <getopt.h>
#include <time.h>
// help 显示内容
static void print_usage(const char *pname)
{
printf("Usage: %s -d devname -b baudrate -s string "
"\nExample : %s -d /dev/ttymxc2 [-b 115200 -s forlinxsendata]"
"\n\t -d devname can list in /dev"
"\n\t -b baudrate ,list in doc,default is 115200"
"\n\t -s string ,the string for sending\n",
pname,pname
);
}
int main(int argc, char **argv)
{
//signal(SIGINT,SignHandler);
int next_option;
//执行获得参数,
printf("param is 'hd:b:s:t:'\n\n");
/* 用于获得执行程序时输入的参数,根据你要设定的参数来进行调整,如下是三个参数的情况*/
const char *const short_opt = "d:b:s:t:";
const struct option long_opt[] = {
{"devices",1,NULL,'d'},
{"baudrate",1,NULL,'b'},
{"string",1,NULL,'s'},
{"times",1,NULL,'t'},
{NULL,0,NULL,0},
};
int ret = 0;
int index = 0;
if(argc <= 1)
printf("please input param\n");
while((ret = getopt_long(argc, argv, short_opt, long_opt, &index)) != -1)
{
printf("getopt_long:\t ret = %c\t", ret);
printf("optarg = %s\t", optarg);
printf("optind = %d\t", optind);
printf("argv[optind] = %s\t", argv[optind]);
printf("optopt = %d\n", optopt);
}
return 0;
}
执行效果如下:
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$ ./getopt_long
param is 'hd:b:s:t:'
please input param
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$ ./getopt_long --h
param is 'hd:b:s:t:'
./getopt_long: unrecognized option '--h'
getopt_long: ret = ? optarg = (null) optind = 2 argv[optind] = (null) optopt = 0
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$ ./getopt_long -d /dev/ttymxc1 -d 115200 -s string -t 100000
param is 'hd:b:s:t:'
getopt_long: ret = d optarg = /dev/ttymxc1 optind = 3 argv[optind] = -d optopt = 0
getopt_long: ret = d optarg = 115200 optind = 5 argv[optind] = -s optopt = 0
getopt_long: ret = s optarg = string optind = 7 argv[optind] = -t optopt = 0
getopt_long: ret = t optarg = 100000 optind = 9 argv[optind] = (null) optopt = 0
forlinx@ubuntu:/mnt/hgfs/share/6ulx-s2/armc/getopt$
编写不易,如果对您有帮助,点个赞再走呗。