丽水公司网站建设绿色郑州网站
news/
2025/9/22 20:26:17/
文章来源:
丽水公司网站建设,绿色郑州网站,网络公司网站源码下载,计算机应用技术网站开发基础知识一、linux应用程序如何接收参数#xff1f;
1. argc、argv
Linux应用程序执行时#xff0c;我们往往通过命令行带入参数给程序#xff0c;比如
ls /dev/ -l 其中参数 /dev/ 、-l都是作为参数传递给命令 ls
应用程序又是如何接收这些参数的#xff1f;
通常应用程序都…一、linux应用程序如何接收参数
1. argc、argv
Linux应用程序执行时我们往往通过命令行带入参数给程序比如
ls /dev/ -l 其中参数 /dev/ 、-l都是作为参数传递给命令 ls
应用程序又是如何接收这些参数的
通常应用程序都是从main函数开始执行传统的main函数风格如下
int main(int argc, char* argv[])
argc:
程序的命令行参数的数量用于统计参数数量。
argv:
是一个指向一个字符串数组的指针数组包含了参数每个字符串就是一个参数最后一个元素为0。
过一般习惯使用多级指针来操作字符串。*char argv[]有时候我们也写成char argv
**argv[]**是一个存放字符类型元素地址的数组。
因为 C 中是有字符串的概念的将每个字符存放在 char 数组最后一个元素为**\0**表示字符串的结束。
**printf(%s)**就是输出字符串。
并且一般使用argv指针来访问、处理argv[]数组的内容。
C语言中数组就是一个指针加偏移量。
所以argv则是指向一个指针数组argv[]的指针不用定义直接可以用。
在argv[]数组中存放的的指针指向输入命令的各部分**调用程序、选项、参数**。
2. 举例
下面我们用一个实例来理解argc和argv
/*
* argc: 命令行参数的个数
* argv: 字符指针数组指向各个命令行参数的字符指针所构成的数组
*/
int main(int argc, char* argv[]) // 接收命令行参数
{printf(argc%d\n,argc);for (int i 0; i argc; i) {printf(argv[%d]: %s\n, i, argv[i]); // 遍历字符指针数组argv}return 0;
}执行结果
pengubuntu:~/work$ ./peng arg1 arg2 arg3
argc4
argv[0]: ./peng
argv[1]: arg1
argv[2]: arg2
argv[3]: arg3
参数与argcargv关系如下
二、选项
1. 选项含义
linux程序除了上述情况以外我们还经常会遇到一个使用方法就是选项应用
比如ping命令
pengubuntu:~/work$ ping -h
Usage: ping [-aAbBdDfhLnOqrRUvV] [-c count] [-i interval] [-I interface][-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos][-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option][-w deadline] [-W timeout] [hop1 ...] destination参数含义
-a尝试将IP地址解析为主机名。
-A使用响应数据包中的附加数据。
-b允许ping广播地址。
-B不允许ping广播地址。
-c count设置要发送的数据包数量。
-d使用SO_DEBUG选项。
-D不将socket设为分离模式。
-f向目标发送一个“强制”数据包。
-h显示帮助信息。
-i interval设置发送数据包之间的时间间隔。
-I interface设置要使用的网络接口。
-l preload设置发送的数据包数量。
-m mark设置ping数据包的标记。
-M pmtudisc_option设置MTU发现选项。
-n不要将IP地址解析为主机名。
-O启用原始输出。
-p pattern设置数据包的模式。
-Q tos设置服务类型。
-r不使用路由表直接发送数据包到目标主机。
-R启用记录路由。
-s packetsize设置数据包的大小。
-S sndbuf设置套接字的发送缓冲区大小。
-t ttl设置数据包的TTL值。
-T timestamp_option设置时间戳选项。
-U使用UDP数据包。
-v显示详细的ping命令输出。
-V显示ping命令的版本信息。
-w deadline设置等待响应的时间。
-W timeout设置等待响应的超时时间。destination指定要ping的目标主机或IP地址。这些 - 开头的都是选项 []表示可选的意思
[-aAbBdDfhLnOqrRUvV] 是无参的选项
[-c count] [-i interval] [-I interface]
[-m mark] [-M pmtudisc_option] [-l preload] [-p pattern] [-Q tos]
[-s packetsize] [-S sndbuf] [-t ttl] [-T timestamp_option]
[-w deadline] [-W timeout] [hop1 ...] 这些都是有参数的选项
destination 必须填写的参数前辈们利用这点发明了“UNIX 风格”的命令选项前面加一个横杠-用于区分选项和参数。
2. 程序如何区分参数和选项
在程序的代码实现中按照 UNIX 的代码惯例上来直接跳过第一个然后判断指针指向的字符串第一个字符是不是-如果是的那么进入一个switch判断用case列出多种支持的情况下应该执行什么代码。
例如下面这样就可以判断选项和处理参数:
int c;
while (--argc 0 (*argv)[0] - {while (c *argv[0] {switch(c){case x:...break;case n:...break;default:printf(xxx: illegal opyion %c\n, c);...break;}}
}3. getopt、getopt_long
事实这么处理选项参数是比较麻烦的
linux提供了选项解析的函数
// 头文件
#includeunistd.h
#includegetopt.h /*所在头文件 */
int getopt(intargc, char * const argv[], const char *optstring);
int getopt_long(int argc, char * const argv[], const char *optstring,const struct option *longopts, int*longindex);
int getopt_long_only(int argc, char * const argv[],const char *optstring,const struct option *longopts, int*longindex);
extern char *optarg; /*系统声明的全局变量 */
extern int optind, opterr, optopt;三、getopt
1. 定义
int getopt(int argc, char * const argv[], const char *optstring);
功能getopt是用来解析命令行选项参数的但是只能解析短选项: **-d 100**,不能解析长选项**--prefix**
参数argcmain()函数传递过来的参数的个数argvmain()函数传递过来的参数的字符串指针数组optstring选项字符串告知 getopt()可以处理哪个选项以及哪个选项需要参数
返回如果选项成功找到返回选项字母如果所有命令行选项都解析完毕返回 -1如果遇到选项字符不在 optstring 中返回字符 ‘?’如果遇到丢失参数那么返回值依赖于 optstring 中第一个字符如果第一个字符是 ‘:’ 则返回’:‘否则返回’?并提示出错误信息。2. optstring 含义 【重要】
下边重点举例说明optstring的格式意义
char*optstring “ab:c::”;
单个字符a 表示选项a没有参数 格式-a即可不加参数
单字符加冒号b: 表示选项b有且必须加参数 格式-b 100或-b100,但-b100错
单字符加2冒号c:: 表示选项c可以有也可以无 格式-c200其它格式错误上面这个 optstring 在传入之后getopt 函数将依次检查命令行是否指定了 -a -b -c(这需要多次调用 getopt 函数直到其返回-1)当检查到上面某一个参数被指定时函数会返回被指定的参数名称(即该字母)
系统声明的4个全局变量含义如下
optarg —— 指向当前选项参数(如果有)的指针。
optind —— 再次调用 getopt() 时的下一个 argv指针的索引。
optopt —— 最后一个未知选项。
opterr —— 如果不希望getopt()打印出错信息则只要将全域变量opterr设为0即可。3. 实例
说千道万不如来一个实例
#includestdio.h
#includeunistd.h
#includegetopt.h
int main(intargc, char *argv[])
{int opt;char *string a::b:c:d;while ((opt getopt(argc, argv, string))! -1){ printf(opt %c\t\t, opt);printf(optarg %s\t\t,optarg);printf(optind %d\t\t,optind);printf(argv[optind] %s\n,argv[optind]);}
}正确输入参数执行结果如下
pengubuntu:~/work/test$ ./peng -a100 -b 200 -c 300 -d
opt a optarg 100 optind 2 argv[optind] -b
opt b optarg 200 optind 4 argv[optind] -c
opt c optarg 300 optind 6 argv[optind] -d
opt d optarg (null) optind 7 argv[optind] (null)或者
ork/test$ ./peng -a100 -b200 -c300 -d
opt a optarg 100 optind 2 argv[optind] -b200
opt b optarg 200 optind 3 argv[optind] -c300
opt c optarg 300 optind 4 argv[optind] -d
opt d optarg (null) optind 5 argv[optind] (null)输入选项参数错误的情况
pengubuntu:~/work/test$ ./peng -a 100 -b 200 -c 300 -d
opt a optarg (null) optind 2 argv[optind] 100
opt b optarg 200 optind 5 argv[optind] -c
opt c optarg 300 optind 7 argv[optind] -d
opt d optarg (null) optind 8 argv[optind] (null)导致解析错误第一个 optarg null实际输入参数 100由于格式不正确造成的(可选参数格式固定)
参数丢失也会导致错误
pengubuntu:~/work/test$ ./peng -a -b 200 -c
opt a optarg (null) optind 2 argv[optind] -b
opt b optarg 200 optind 4 argv[optind] -c
./peng: option requires an argument -- c
opt ? optarg (null) optind 5 argv[optind] (null)c选项是必须有参数的
命令行选项未定义-e选项未在optstring中定义会报错
pengubuntu:~/work/test$ ./peng -t
./peng: invalid option -- t
opt ? optarg (null) optind 2 argv[optind] (null)四、getopt_long
1. 定义
int getopt_long(int argc, char * const argv[], const char *optstring,
const struct option *longopts,int *longindex);
功能包含 getopt 功能增加了解析长选项的功能如--prefix --help
参数longopts 指明了长参数的名称和属性longindex 如果longindex非空它指向的变量将记录当前找到参数符合longopts里的第几个元素的描述即是 longopts 的下标值
返回对于短选项返回值同 getopt 函数对于长选项如果 flag 是 NULL 返回 val 否则返回 0 对于错误情况返回值同 getopt 函数2. struct option
struct option {const char *name; /* 参数名称 */int has_arg; /* 指明是否带有参数 */int *flag; /* flagNULL时,返回value;不为空时,*flagval,返回0 */int val; /* 用于指定函数找到选项的返回值或flag非空时指定*flag的值 */
}; 参数has_arg 说明 has_arg 指明是否带参数值其数值可选 no_argument 表明长选项不带参数如–name, --helprequired_argument 表明长选项必须带参数如–prefix /root或 --prefix/rootoptional_argument 表明长选项的参数是可选的如–help或 –prefix/root其它都是错误3. 实例
#includestdio.h
#includeunistd.h
#includegetopt.h
int main(intargc, char *argv[])
{int opt;int digit_optind 0;int option_index 0;char *string a::b:c:d;static struct option long_options[] { {reqarg, required_argument,NULL, r},{optarg, optional_argument,NULL, o},{noarg, no_argument, NULL,n},{NULL, 0, NULL, 0},}; while((opt getopt_long_only(argc,argv,string,long_options,option_index))! -1){ printf(opt %c\t\t, opt);printf(optarg %s\t\t,optarg);printf(optind %d\t\t,optind);printf(argv[optind] %s\t\t, argv[optind]);printf(option_index %d\n,option_index);}
}正确执行命令
pengubuntu:~/work/test$ ./long --reqarg 100 --optarg200 --noarg
opt r optarg 100 optind 3 argv[optind] --optarg200 option_index 0
opt o optarg 200 optind 4 argv[optind] --noarg option_index 1
opt n optarg (null) optind 5 argv[optind] (null) option_index 2或者
pengubuntu:~/work/test$ ./long –reqarg100 --optarg200 --noarg
opt o optarg 200 optind 3 argv[optind] --noarg option_index 1
opt n optarg (null) optind 4 argv[optind] (null) option_index 2可选选项可以不给参数
pengubuntu:~/work/test$ ./long --reqarg 100 --optarg --noarg
opt r optarg 100 optind 3 argv[optind] --optarg option_index 0
opt o optarg (null) optind 4 argv[optind] --noarg option_index 1
opt n optarg (null) optind 5 argv[optind] (null) option_index 2输入长选项错误的情况
pengubuntu:~/work/test$ ./long --reqarg 100 --optarg 200 --noarg
opt r optarg 100 optind 3 argv[optind] --optarg option_index 0
opt o optarg (null) optind 4 argv[optind] 200 option_index 1
opt n optarg (null) optind 6 argv[optind] (null) option_index 2五、getopt_long_only
getopt_long_only 函数与 getopt_long 函数使用相同的参数表在功能上基本一致
只是 getopt_long 只将 --name 当作长参数但 getopt_long_only 会将 --name 和 -name 两种选项都当作长参数来匹配
getopt_long_only 如果选项 -name 不能在 longopts 中匹配但能匹配一个短选项它就会解析为短选项。
六、综合实例
下面这个例子是一口君从开源项目ifplug提取出来的命令提取小例子
大家可以根据自己需要基于这个框架定制自己的程序。
#define _GNU_SOURCE
#include stdlib.h
#include stdio.h
#include string.h
#include unistd.h
#include errno.h
#include getopt.h
#include sys/param.h#define ETHCHECKD_VERSION 1.1int delay_up 0;
char *interface eth0;void usage(char *p) {if (strrchr(p, /))p strchr(p, /)1;printf(%s [options]\n -i --ifaceIFACE Specify ethernet interface (%s)\n -d --delay-upSECS Specify delay time (%i)\n -h --help Show this help\n,p,interface,delay_up);
}void parse_args(int argc, char *argv[]) {static struct option long_options[] {{iface, required_argument, 0, i},{delay-up, required_argument, 0, d},{help, no_argument, 0, h},{version, no_argument, 0, v},{0, 0, 0, 0}};int option_index 0;int help 0, _kill 0, _check 0, _version 0, _suspend 0, _resume 0, _info 0;for (;;) {int c;if ((c getopt_long(argc, argv, i:d:hv, long_options, option_index)) 0)break;switch (c) {case i :interface strdup(optarg);printf(interface %s\n,interface);break;case d:delay_up atoi(optarg);printf(delay_up %d\n,delay_up);break;case h:usage(argv[0]);break;case v:printf(peng ETHCHECKD_VERSION\n);break;default:fprintf(stderr, Unknown parameter.\n);exit(1);}}}static volatile int alarmed 0;int main(int argc, char* argv[]) {parse_args(argc, argv);return 0;
}下面是测试结果
短选项
pengubuntu:~/work/test$ ./param -h
param [options]-i --ifaceIFACE Specify ethernet interface (eth0)-d --delay-upSECS Specify delay time (0)-h --help Show this help
pengubuntu:~/work/test$ ./param -v
peng 1.1pengubuntu:~/work/test$ ./param -vh
peng 1.1
param [options]-i --ifaceIFACE Specify ethernet interface (eth0)-d --delay-upSECS Specify delay time (0)-h --help Show this help pengubuntu:~/work/test$ ./param -i eth3 -d 15
interface eth3
delay_up 15 pengubuntu:~/work/test$ ./param -i eth3 -d 15 -h
interface eth3
delay_up 15
param [options]-i --ifaceIFACE Specify ethernet interface (eth3)-d --delay-upSECS Specify delay time (15)-h --help Show this help长选项
pengubuntu:~/work/test$ ./param --help
param [options]-i --ifaceIFACE Specify ethernet interface (eth0)-d --delay-upSECS Specify delay time (0)-h --help Show this helppengubuntu:~/work/test$ ./param --version
peng 1.1pengubuntu:~/work/test$ ./param --iface eth3 --delay-up 15
interface eth3
delay_up 15talk is cheap
test this code快操练起来吧
更多嵌入式linux资料后台留言资料
也可以加一口君好友
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/910266.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!