GNU getopt not populating optarg
我正在尝试使用GNU
1 | ./my_program -E 16 -t path/to/file |
我目前的期望是,如果我有以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 | long arg; int e_val; char *t_str; while ((arg = getopt(argc, argv,"E:t:")) != -1) { switch(arg) { case 'E': e_val = *optarg; // e_val = 16 break; case 't': t_str = optarg; break; } } |
然后
但是,我似乎无法弄清楚如何访问这些参数的实际值。在我开始在
1 2 3 4 5 6 7 8 9 10 11 12 13 | Starting program: /stack/overflow/example -E 16 -t stackoverflow Breakpoint 1, get_arguments (argc=5, argv=0x7fffffffe318) at stack_overflow.c:233 233 while ((arg = getopt(argc, argv,"E:t:")) != -1) (gdb) n 235 switch (arg) (gdb) 254 e_val = *optarg; (gdb) p optarg $6 = 0x0 (gdb) x/1xw optarg 0x0: Cannot access memory at address 0x0 (gdb) p /x arg $7 = 0x45 // ASCII for 'E' |
为什么optarg无法设置?如果
最后一点,我简要介绍了gdb的
回溯:
1 2 3 4 5 6 7 | #0 _getopt_internal (argc=<value optimized out>, argv=<value optimized out>, optstring=<value optimized out>, longopts=<value optimized out>, longind=<value optimized out>, long_only=<value optimized out>, posixly_correct=0) at getopt.c:1135 #1 0x00007ffff7894138 in getopt (argc=<value optimized out>, argv=<value optimized out>, optstring=<value optimized out>) at getopt.c:1145 #2 0x0000000000400cd6 in get_arguments (argc=5, argv=0x7fffffffe318) at stackoverflow.c:233 #3 0x0000000000400875 in main (argc=5, argv=0x7fffffffe318) at stackoverflow.c:82 |
正在执行的代码:
1 2 3 4 5 6 7 8 9 10 11 | (gdb) l 1130 1131 result = _getopt_internal_r (argc, argv, optstring, longopts, 1132 longind, long_only, &getopt_data, 1133 posixly_correct); 1134 1135 optind = getopt_data.optind; 1136 optarg = getopt_data.optarg; 1137 optopt = getopt_data.optopt; 1138 1139 return result; |
1 2 3 4 5 6 7 8 | (gdb) n 1136 optarg = getopt_data.optarg; (gdb) 1135 optind = getopt_data.optind; (gdb) p optarg $10 = 0x0 (gdb) p getopt_data.optarg $11 = 0x7fffffffe60d"16" |
请注意,此处未设置
这并不是真正的答案,但是太大了,无法发表评论。
该代码在严格的编译选项下可以干净地编译:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | #include <getopt.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char **argv) { long arg; int e_val = -1; char *t_str ="pygmalion"; while ((arg = getopt(argc, argv,"E:t:")) != -1) { switch (arg) { case 'E': e_val = atoi(optarg); // e_val = 16 break; case 't': t_str = optarg; break; } } printf("e_val = %d\ ", e_val); printf("t_str = %s\ ", t_str); return 0; } |
编译并运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | $ gcc -g -O3 -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \\ > -Wold-style-definition -Wold-style-declaration -Werror go.c -o go $ ./go -E 16 -t path/to/file e_val = 16 t_str = path/to/file $ ./go -E 16 e_val = 16 t_str = pygmalion $ ./go -t pygmalion e_val = -1 t_str = pygmalion $ ./go e_val = -1 t_str = pygmalion $ |
在带有GCC 5.1.0的Ubuntu 14.04 LTS衍生产品上进行测试。 因此,从表面上看,该代码是正确的。 这又表明问题出在周围的代码中。 您链接的对象是否也定义了
如果使用我刚刚显示的代码并运行它,您会得到什么? 如果它可以运行,但是您的大程序无法运行,则您的大程序中有某种原因在某种程度上引起了麻烦。