长参数getopt_long()

getopt_long支持长选项的命令行解析,函数中的参数argc和argv通常直接从main()的两个参数传递而来

头文件
#include<getopt.h>

函数原型
int getopt_long(int argc,char * const argv[],const char *optstring,const struct option *longopts,int *longindex)

函数说明
getopt被用来解析命令行选项参数。
getopt_long支持长选项的命令行解析,函数中的参数argc和argv通常直接从main()的两个参数传递而来。optstring是选项参数组成的字符串。

字符串optstring可以下列元素:
1. 单个字符,表示选项,

2. 单个字符后接一个冒号:表示该选项后必须跟一个参数。参数紧跟在选项后或者以空格隔开。该参数的指针赋给optarg。

3. 单个字符后跟两个冒号,表示该选项后可以有参数也可以没有参数。如果有参数,参数必须紧跟在选项后不能以空格隔开。该参数的指针赋给optarg。(这个特性是GNU的扩张)。
optstring是一个字符串,表示可以接受的参数。例如,"a:b:cd",表示可以接受的参数是a,b,c,d,其中,a和b参数后面跟有更多的参数值。(例如:-a host --b name)。

参数longopts,其实是一个结构的实例:

复制代码 代码如下:

struct option {
const char *name; //name表示的是长参数名
int has_arg; //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值
// required_argument(或者是1),表示该参数后面一定要跟个参数值
// optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
int *flag;
//用来决定,getopt_long()的返回值到底是什么。如果flag是null,则函数会返回与该项option匹配的val值
int val; //和flag联合决定返回值
}

给个例子:
复制代码 代码如下:

struct option long_options[] = {
{"a123", required_argument, 0, 'a'},
{"c123", no_argument, 0, 'c'},
}

现在,如果命令行的参数是-a 123,那么调用getopt_long()将返回字符'a',并且将字符串123由optarg返回(注意注意!字符串123由optarg带回!optarg不需要定义,在getopt.h中已经有定义),那么,如果命令行参数是-c,那么调用getopt_long()将返回字符'c',而此时,optarg是null。最后,当getopt_long()将命令行所有参数全部解析完成后,返回-1。

参数longopts,其实是一个结构的实例:

复制代码 代码如下:

struct option {
const char *name; //name表示的是长参数名
int has_arg; //has_arg有3个值,no_argument(或者是0),表示该参数后面不跟参数值
// required_argument(或者是1),表示该参数后面一定要跟个参数值
// optional_argument(或者是2),表示该参数后面可以跟,也可以不跟参数值
int *flag;
//用来决定,getopt_long()的返回值到底是什么。如果flag是null,则函数会返回与该项option匹配的val值
int val; //和flag联合决定返回值
}

给个例子:
复制代码 代码如下:

struct option long_options[] = {
{"a123", required_argument, 0, 'a'},
{"c123", no_argument, 0, 'c'},
}

现在,如果命令行的参数是-a 123,那么调用getopt_long()将返回字符'a',并且将字符串123由optarg返回(注意注意!字符串123由optarg带回!optarg不需要定义,在getopt.h中已经有定义),那么,如果命令行参数是-c,那么调用getopt_long()将返回字符'c',而此时,optarg是null。最后,当getopt_long()将命令行所有参数全部解析完成后,返回-1。
范例
复制代码 代码如下:

#include <stdio.h>
#include <getopt.h>
char *l_opt_arg;
char* const short_options = "nbl:";
struct option long_options[] = {
{ "name", 0, NULL, 'n' },
{ "bf_name", 0, NULL, 'b' },
{ "love", 1, NULL, 'l' },
{ 0, 0, 0, 0},
};
int main(int argc, char *argv[])
{
int c;
while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
{
switch (c)
{
case 'n':
printf("My name is XL./n");
break;
case 'b':
printf("His name is ST./n");
break;
case 'l':
l_opt_arg = optarg;
printf("Our love is %s!/n", l_opt_arg);
break;
}
}
return 0;
}
[root@localhost wyp]# gcc -o getopt getopt.c
[root@localhost wyp]# ./getopt -n -b -l forever
My name is XL.
His name is ST.
Our love is forever!
[root@localhost liuxltest]#
[root@localhost liuxltest]# ./getopt -nb -l forever
My name is XL.
His name is ST.
Our love is forever!
[root@localhost liuxltest]# ./getopt -nbl forever
My name is XL.
His name is ST.
Our love is forever!

getopt_long函数的返回值问题

12-07

[size=14px]如下代码中,c = getopt_long_only(argc, argv, "abc:d:f:012", long_options, &option_index)中的c为什么还会取到'a'、'b'、'd'的值呢?struct option long_options[]中不是设置了只能取到'0'、'c'、'f'的值吗?[/size]rn[code=c]rn#include /* for printf */rn#include /* for exit */rn#include rn rnint main(int argc, char **argv) rnrn int c;rn int digit_optind = 0;rn int flag = 0;rn rn rn while (1) rn int this_option_optind = optind ? optind : 1;rn int option_index = 0;rn static struct option long_options[] = rn "add", required_argument, 0, 0 ,rn "append", no_argument, 0, 0 ,rn "delete", required_argument, 0, 0 ,rn "verbose", no_argument, 0, 0 ,rn "create", required_argument, 0, 'c',rn "file", required_argument, 0, 'f',rn 0, 0, 0, 0 rn ;rn rn rn c = getopt_long_only(argc, argv, "abc:d:f:012", long_options, &option_index);rn if (c == -1)rn break;rn rn rn switch (c) rn case 0:rn printf("option %s", long_options[option_index].name);rn rn if (optarg)rn printf(" with arg %s", optarg);rn rn rn printf("\n");rn break;rn rn rn case '0':rn case '1':rn case '2':rn if (digit_optind != 0 && digit_optind != this_option_optind)rn printf("digits occur in two different argv-elements.\n");rn digit_optind = this_option_optind;rn printf("option %c\n", c);rn break;rn rn rn case 'a':rn printf("option a\n");rn break;rn rn rn case 'b':rn printf("option b\n");rn break;rn rn rn case 'c':rn printf("option c with value '%s'\n", optarg);rn break;rn rn rn case 'd':rn printf("option d with value '%s'\n", optarg);rn break;rn case 'f':rn printf("option f with value '%s'\n", optarg);rn break;rn case '?':rn break;rn rn rn default:rn printf("?? getopt returned character code 0%o ??\n", c);rn rn rn rn rn if (optind < argc) rn printf("non-option ARGV-elements: ");rn while (optind < argc)rn printf("%s ", argv[optind++]);rn printf("\n");rn rn rn rn exit(EXIT_SUCCESS);rnrn[/code]

标题一定要长...长...长...长...长...长...长...长...长...长...长...长...长...长...长...长...长...长

10-31

[code=Java]rnimport java.awt.Dimension;rnimport java.awt.Point;rnimport java.awt.Toolkit;rnimport java.awt.event.WindowAdapter;rnimport java.awt.event.WindowEvent;rnimport java.awt.event.WindowStateListener;rnimport java.util.ArrayList;rnimport java.util.List;rnrnimport javax.imageio.ImageIO;rnimport javax.swing.ImageIcon;rnimport javax.swing.JFrame;rnimport javax.swing.JLabel;rnimport javax.swing.SwingUtilities;rnrnimport com.sun.awt.AWTUtilities;rnimport java.awt.event.KeyAdapter;rnimport java.awt.event.KeyEvent;rnrnpublic class FlowerRain extends JFrame rnrn private static final long serialVersionUID = -8037287523655159012L;rnrn private int num = 99;// 花朵数量rn private int speed = 3;// 下降速度rn private boolean flag = true;rn private List labelList = new ArrayList(num);rn private Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();rn private ImageIcon icon = new ImageIcon(ImageIO.read(this.getClass().getResourceAsStream("flower.gif")));// 花朵图片rnrn public FlowerRain() throws Exception rnrn getContentPane().setLayout(null);rn setTitle("漫天花雨");rn setSize(screenSize);rn setResizable(false);rn setUndecorated(true);rn setAlwaysOnTop(true);rn setLocationRelativeTo(null);rn setIconImage(icon.getImage());rn AWTUtilities.setWindowOpaque(this, false);rn setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);rnrn // 防止最小化rn addWindowStateListener(new WindowStateListener() rn public void windowStateChanged(WindowEvent e) rn if (getState() == 1) rn setState(0);rn rn rn );rnrn // Ctrl + E 关闭窗口rn addKeyListener(new KeyAdapter() rn public void keyPressed(KeyEvent e) rn if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_E) rn dispatchEvent(new WindowEvent(FlowerRain.this, WindowEvent.WINDOW_CLOSING));rn rn rn );rnrn addWindowListener(new WindowAdapter() rn @Overridern public void windowClosing(WindowEvent e) rn flag = false;// 将线程循环标志置为falsern rn );rnrn for (int i = 0; i < num; i++) rn JLabel jlbl = new JLabel(icon);rn jlbl.setSize(20, 20);rn jlbl.setLocation(random(screenSize.width), random(screenSize.height));rnrn labelList.add(jlbl);rn add(jlbl);rn rnrn rnrn public void move() rn new Thread() rn public void run() rn while (flag) rn try rn SwingUtilities.invokeLater(new Runnable() rn public void run() rn for (int i = 0; i < labelList.size(); i++) rn JLabel jlbl = labelList.get(i);rn Point location = jlbl.getLocation();rnrn jlbl.setLocation(location.x + (i % 5 - 2), location.y + speed);rnrn location = jlbl.getLocation();rn if (location.y >= screenSize.height || location.x <= 0 || location.x >= screenSize.width) rn jlbl.setLocation(random(screenSize.width), 0);rn rn rn rn );rn Thread.sleep(100);rn catch (Exception e) rn e.printStackTrace();rn rn rn ;rn .start();rnrn rnrn public void start() rn SwingUtilities.invokeLater(new Runnable() rn public void run() rn try rn setVisible(true);rn move();rn catch (Exception e) rn e.printStackTrace();rn rn rn );rn rnrn public int random(int max) rn return (int) (Math.random() * max);rn rnrn public int random(int min, int max) rn return random(max - min) + min;rn rnrn public static void main(String[] args) throws Exception rn new FlowerRain().start();rn rnrn[/code]rnrn[img=http://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/001/face/63.gif][/img]

新手疑问:getopt_long()重入问题

05-31

大家好。rn 我在开发一个命令行处理工具,其中使用getopt_long()函数来处理用户的多选项输入,但是发现如果输入一条命令比较长的时候,第一次可以执行成功,但是第二次就不能执行成功,第三次可以成功,第四次又不能,这样循环往复。具体现象如下:rn> lanconfig --lan_ipaddr 192.168.10.209 (用户输入的命令)rndone! (这是执行成功后我自己的调试信息)rn> lanconfig --lan_ipaddr 192.168.10.209 (再执行一遍同样的命令)rnlanconfig: unrecognized option '--09' (这一行是getopt_long()输出的错误信息)rnrn我不明白为什么该函数在第二次调用时,居然找到一个"--09"的选项。我怀疑是我用了某个全局变量但是没有重新初始化导致的,后来在社区找到一个05年的帖,有类似的问题,这位大侠是用下面的语句清理了几个变量:rn __getopt_initialized = 0; //如果是1的话是不会获取optstring rn last_nonopt = 1; //后一个参数把他重置回第一个 rn first_nonopt = 1; //前一个参数把他重置回第一个 rn optind = 1; //初始argv[],可以为0,不过程序是不读取argv[0] rn但是除了最后的optind是全局变量之外,其他三个参数都是getopt.c内部的静态变量,外部引用都会报“引用了没有定义的变量”错误,而我自己的程序中在调用前的确是将optind重置为1了。 rnrn开发的系统环境是Fadora 7,GCC版本是3.4.6,程序的主流程如下:rnint main()rnrn while(1)rn rn 等待用户输入命令;rn 分析输入命令到argc,argv变量中;rn optind = 1;rn result = getopt_long(argc, argv, ...);rn 根据result处理;rn rnrn程序对照一些范例做过自检,流程上没有问题,因为在命令不太长的时候可以正确执行,并且optstring、option结构都没有错。rnrn希望各位能给我一些指点或者建议,谢谢大家。

没有更多推荐了,返回首页

私密
私密原因:
请选择设置私密原因
  • 广告
  • 抄袭
  • 版权
  • 政治
  • 色情
  • 无意义
  • 其他
其他原因:
120
出错啦
系统繁忙,请稍后再试