when long option is given as argument to short option - getopt_long
我正在学习如何使用getopt_long函数接受命令行参数,我设置了2个长选项'filename'(必需的arg)和'clear'(没有arg)以及2个简短的args'a'(带有arg)和'b'(没有 arg)当我执行时:
1 | $ ./a.out -a --filename=test.txt |
而不显示'a'没有arg,而是显示'a'的optarg为:
--filename = text.txt并跳过文件名长选项
有什么解决办法吗?
我的代码是:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include <iostream> #include <getopt.h> using namespace std; int main(int argc, char* argv[]){ static struct option long_options[] = { {"filename",1,0,0}, {"clear",0,0,0}, {NULL,0,0,0} }; int op,option_index = 0; string filename; while((op = getopt_long(argc,argv,"a:b",long_options,&option_index))!=-1){ switch (op){ case 0: switch(option_index){ case 0: filename = optarg; cout<<filename<<endl; break; case 1: cout<<"clear is yes "; break; default: cout<<"Please enter valid long option "; break; }break; case 'a': cout<<"a is set as"<<optarg<<endl; //cout<<optarg<<endl; break; case 'b': cout<<"b is set"<<endl; break; default: cout<<"Please enter valid Arguments"<<endl; break; } } cout<<" "; return 0; } |
我找到了一个更好的答案,我的朋友告诉我。
我可以直接使用::代替:这意味着'a'需要一个可选参数,因此getopt_long将检查arg是否为选项,如果没有arg或arg为选项,则返回0,我可以单独处理,如果'a'具有非选项arg,那里的情况可以正常处理。
最终代码为:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 | #include <iostream> #include <getopt.h> using namespace std; int main(int argc, char* argv[]){ static struct option long_options[] = { {"filename",1,0,0}, {"clear",0,0,0}, {NULL,0,0,0} }; int op,option_index = 0; string filename; while((op = getopt_long(argc,argv,"a::b",long_options,&option_index))!=-1){ switch (op){ case 0: switch(option_index){ case 0: filename = optarg; cout<<filename<<endl; break; case 1: cout<<"clear is yes "; break; default: cout<<"Please enter valid long option "; break; }break; case 'a': if(optarg) cout<<"a is set as"<<optarg<<endl; else cout<<"a needs an argument"<<endl; //cout<<optarg<<endl; break; case 'b': cout<<"b is set"<<endl; break; default: cout<<"Please enter valid Arguments"<<endl; break; } } cout<<" "; return 0; } |
无需对此进行任何硬编码。
一种方法是查看
这是一个例子:
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 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | #include <iostream> #include <getopt.h> #include <string.h> using namespace std; int str_startswith( char const* s, char const* prefix) { return strncmp(prefix, s, strlen(prefix)) == 0; } bool is_option(char const* arg) { int result = 0; result = result || str_startswith( arg,"--filename="); result = result || (strcmp( arg,"--clear") == 0); result = result || (strcmp( arg,"-b") == 0); return result; } int main(int argc, char* argv[]){ static struct option long_options[] = { {"filename",1,0,0}, {"clear",0,0,0}, {NULL,0,0,0} }; int op,option_index = 0; string filename; while((op = getopt_long(argc,argv,"a:b",long_options,&option_index))!=-1){ switch (op){ case 0: switch(option_index){ case 0: filename = optarg; cout <<"filename is:" <<filename<<endl; break; case 1: cout<<"clear is yes "; break; default: cout<<"Please enter valid long option "; break; }break; case 'a': if (is_option(optarg)) { cout <<"-a option requires an argument" << endl; optind -= 1; // put the option back into consideration for getopt_long() } else { cout <<"a is set as" << optarg << endl; } break; case 'b': cout<<"b is set"<<endl; break; default: cout<<"Please enter valid Arguments"<<endl; break; } } cout<<" "; return 0; } |
我希望改善此状况的一种方法是具有检查参数是否可能为选项的功能,而不是通过与
实际上,由于这是我几个星期以来第二次遇到关于SO的问题(我找不到另一个),因此为