getopt_long/get_opt是否移动argv指针?改写get_some_switches相关疑问
关于用getopt_long()改写get_some_switches()的疑问与解答
需要用getopt_long()改写Larry Wall补丁1.3中的get_some_switches()函数,原函数代码如下:
get_some_switches() { register char *s; rejname[0] = '\0'; if (!Argc) return; for (Argc--,Argv++; Argc; Argc--,Argv++) { s = Argv[0]; if (strEQ(s,"+")) { return; /* + will be skipped by for loop */ } if (*s != '-' || !s[1]) { if (filec == MAXFILEC) fatal("Too many file arguments.\n"); filearg[filec++] = savestr(s); } else { switch (*++s) { case 'b': origext = savestr(Argv[1]); Argc--,Argv++; break; case 'c': diff_type = CONTEXT_DIFF; break; case 'd': if (chdir(Argv[1]) < 0) fatal("Can't cd to %s.\n",Argv[1]); Argc--,Argv++; break; case 'D': do_defines++; Sprintf(if_defined, "#ifdef %s\n", Argv[1]); Sprintf(not_defined, "#ifndef %s\n", Argv[1]); Sprintf(end_defined, "#endif %s\n", Argv[1]); Argc--,Argv++; break; case 'e': diff_type = ED_DIFF; break; case 'l': canonicalize = TRUE; break; case 'n': diff_type = NORMAL_DIFF; break; case 'o': outname = savestr(Argv[1]); Argc--,Argv++; break; case 'p': usepath = TRUE; /* do not strip path names */ break; case 'r': Strcpy(rejname,Argv[1]); Argc--,Argv++; break; case 'R': reverse = TRUE; break; case 's': verbose = FALSE; break; #ifdef DEBUGGING case 'x': debug = atoi(s+1); break; #endif default: fatal("Unrecognized switch: %s\n",Argv[0]); } } } }
原函数通过循环递减Argc、递增Argv处理参数,遇到'+'或参数耗尽时停止,后续调用该函数时Argc和Argv已指向参数列表的后续位置。针对改写中的疑问,解答如下:
疑问解答
1. getopt_long和getopt是否会推进argv指针?
getopt和getopt_long不会直接修改argv指针本身,它们通过全局变量optind记录下一个待处理的参数索引。每次调用函数时,会基于optind的值读取argv数组的对应元素,处理完成后自动递增optind——这相当于间接推进了参数处理的位置,但argv数组的指针不会被改变。
2. 使用getopt_long替代原函数时,是否需要手动更新Argc和Argv以支持后续调用,还是getopt_long会保留上次处理的位置?
- 不需要手动更新Argc和Argv。
getopt_long依赖全局变量optind追踪当前处理进度,只要不手动重置optind,后续调用会自动从上次停止的位置继续处理参数。 - 注意:首次调用前需确保
optind初始化为1(因为argv[0]是程序名,不属于命令行选项);如果需要重新从头处理参数,才需要手动将optind重置为1。
3. 原代码中的条件!s[1]表示什么含义?
- 原代码中
s指向当前参数字符串(即Argv[0]),!s[1]表示当前参数是单独的-字符,没有后续选项字符。比如用户输入./program -时,s指向字符串"-",s[1]是字符串结束符'\0',!s[1]结果为真。此时原代码会把这个单独的-当作普通文件参数处理,而非命令行选项。
内容的提问来源于stack exchange,提问作者eternallymisty
相关产品推荐
相关产品推荐

