C:以正确的方式解析选项
Posted
技术标签:
【中文标题】C:以正确的方式解析选项【英文标题】:C : Parsing options the right way 【发布时间】:2012-11-28 22:48:34 【问题描述】:我正在尝试解析 C 程序中的两个选项。
程序是这样调用的:
./a.out [OPTIONS] [DIRECTORY 1] [DIRECTORY 2]
程序同步两个目录并有两个选项。 (-r)
用于递归同步(文件夹内的文件夹),(-n)
用于将文件从本地复制到远程,以防远程中不存在。
Options are:
-r : recursive
-n : copy file if it doesn't exist in remote folder
呼唤:
./a.out -r D1 D2
将递归同步从D1
到D2
的所有文件和目录。 D1
中存在且D2
中不存在的文件将被忽略。
然后调用:
./a.cout -rn D1 D2
会做同样的事情,但D1
中存在的文件和D2
中不存在的文件被复制到D2
。
问题是调用./a.out -rn
与调用./a.out -nr
不同,./a.out -r -n
也不起作用,因为(-n)
不是D1
。
这是我实现 main 的方法。
int main(int argc, char** argv)
int next_option = 0;
const char* const short_options = "hrn:";
const struct option long_options[] =
"help", 0, NULL, 'h' ,
"recursive", 1, NULL, 'r' ,
"new", 1, NULL, 'n' ,
NULL, 0, NULL, 0
;
int recursive = 0;
int new = 0;
do
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option)
case 'r':
recursive = 1;
break;
case 'n':
new = 1;
break;
case 'h':
print_help();
return 0;
case -1:
break;
default:
print_help();
return -1;
while(next_option != -1);
sync(argv[2], argv[3], recursive, new);
return EXIT_SUCCESS;
【问题讨论】:
-rn
和-nr
有什么不同?您的实现表明两者应该是等价的。
我向你保证,结果是不一样的。 -rn = 递归:1,新:1 ,-nr = 递归:0,新:1
我还建议您不要在代码中使用 C++ 关键字(如 new
)。只要您使用 C 编译器,它就可以工作,但如果您将来决定切换到 C++,它就不可移植。
那么,问题在于-rn
与-nr
相同,而您不希望它们相同?或者,问题是 getopt 以某种方式读错了?
【参考方案1】:
这里有两个(潜在的)问题:
您的短选项字符串中有一个杂散的:
。这使得-n
可以选择吞下任何后续r
。您还可以设置长选项来接受强制参数。
您以不灵活的方式硬编码了参数编号,并且您没有测试它们是否存在。
试试这个:
int main(int argc, char** argv)
int next_option = 0;
const char* const short_options = "hrn";
extern int optind;
const struct option long_options[] =
"help", no_argument, NULL, 'h' ,
"recursive", no_argument, NULL, 'r' ,
"new", no_argument, NULL, 'n' ,
NULL, no_argument, NULL, 0
;
int recursive = 0;
int new = 0;
do
next_option = getopt_long(argc, argv, short_options, long_options, NULL);
switch(next_option)
case 'r':
recursive = 1;
break;
case 'n':
new = 1;
break;
case 'h':
print_help();
return 0;
case -1:
break;
default:
print_help();
return -1;
while(next_option != -1);
if (optind + 1 >= argc)
return -1;
sync(argv[optind], argv[optind+1], recursive, new);
return EXIT_SUCCESS;
【讨论】:
【参考方案2】:使用诸如-r -n
之类的命令行的问题是因为您在对sync
的调用中硬编码了索引。你不应该那样做。
如果您阅读getopt_long
手册页(当您遇到函数问题时总是这样做!)然后您会注意到这一行:
如果没有更多选项字符,getopt() 返回 -1。那么 optind 是第一个 argv 元素的 argv 中不是选项的索引。
仔细阅读第二句话。
【讨论】:
确实如此,但实际上并不是 OP 的问题。请注意,他从来没有说过-r -n
,他说的是-rn
,在那种情况下,代码是错误的但没有损坏。
@ams 在-rn
与-nr
之后,OP 确实说-r -n
也存在问题。
哦,是的,因为换行,我没有看到。我的错。以上是关于C:以正确的方式解析选项的主要内容,如果未能解决你的问题,请参考以下文章
在启动时以编程方式为 5 个选项卡栏项目设置选项卡栏标题,其中 4 个嵌入在导航控制器中,1 个没有。目标 C