是否可以重复getopt

MiJ*_*Jyn 7 c getopt

我正在尝试使用内置命令创建一个基本shell,我遇到了一些getopt问题.这是输出(使用valgrind):

$ mkdir -p foo/bar
mkdir
-p
foo/bar
FLAGON
$ mkdir -p foo/test
mkdir
-p
foo/test
==15377== Invalid read of size 1
==15377==    at 0x5201BBE: _getopt_internal_r (in /usr/lib/libc-2.17.so)
==15377==    by 0x5202CEA: _getopt_internal (in /usr/lib/libc-2.17.so)
==15377==    by 0x5202D37: getopt (in /usr/lib/libc-2.17.so)
==15377==    by 0x40351A: shell_ns_cmd_mkdir (shell.c:542)
==15377==    by 0x403AB4: normal_shell_cb (shell.c:610)
==15377==    by 0x402E8E: shell_mainloop (shell.c:402)
==15377==    by 0x401B67: main (main.c:52)
==15377==  Address 0x54e0912 is 2 bytes inside a block of size 3 free'd
==15377==    at 0x4C2AD3C: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==15377==    by 0x402C93: shell_mainloop (shell.c:384)
==15377==    by 0x401B67: main (main.c:52)
==15377== 
$ 
Run Code Online (Sandbox Code Playgroud)

这是源(剪辑):

for (i = 0; i < argc; i++) {
    puts(argv[i]);
}
while ((c = getopt(argc, argv, "p")) != -1) {
    switch (c) {
        case 'p':
            puts("FLAGON");
            mkparents = true;
            break;
        case '?':
            fprintf(stderr, "invalid option -- %c", optopt);
            ret = 127;
            goto end;
            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

所以它第一次运行时(mkdir -p)识别它(-p),第二次运行它,它没有.有任何想法吗?

cni*_*tar 16

如果要扫描多个矢量,则需要getopt通过设置optind为1 来重置.

变量optind是要处理的argv []向量的下一个元素的索引.它应由系统初始化为1,并且getopt()在完成argv []的每个元素时应更新它.

如果设置optind为1不起作用,也请尝试0,我想我记得在某处阅读过.

  • 将`optind`设置为1固定它,但我仍然有来自valgrind的警告,所以我尝试将其设置为0,现在它完美地工作.谢谢! (3认同)
  • 请注意,POSIX [`getopt()`](http://pubs.opengroup.org/onlinepubs/9699919799/functions/getopt.html) 表示:_变量 `optind` 是 `argv[ 的下一个元素的索引] ]` 要处理的向量。它应由系统初始化为 1,并且 `getopt()` 将在完成 `argv[]` 的每个元素时更新它。如果应用程序在调用“getopt()”之前将“optind”设置为零,则行为未指定。当 `argv[]` 的元素包含多个选项字符时,未指定 `getopt()` 如何确定哪些选项已被处理。_ [...续...] (2认同)