How to effectively parse this command line in C++?
如何在C++中有效地解析这个命令行?
program -parameter1=value1 -parameter2=value2 -parameter3=value3
How to effectively drop a combination of the parameter and value
如何有效地删除参数和值的组合
-parameter=value
I am trying to use this code but it does not work properly:
我正在尝试使用此代码,但它不能正常工作:
parameter[256], value[256],
while ( --argc > 0 )
{
if ( *argv[argc] == '-' )
{
for ( char * text = argv[argc]; ; )
{
switch ( * ( ++ text ) )
{
case '=' :
{
*value = *( text );
break;
}
default:
{
*parameter = *text;
}
}
}
//Testing parameters and values
}
}
Thanks for your comments and improvements.
感谢您的意见和改进。
更多回答
What do you mean by it does not work properly? Does it fail to tell the parts of each command apart from each other? For example i don't see, how value should be filled because you always access its first byte, the same with parameter.
你说它不能正常工作是什么意思?它无法区分每个命令的各个部分吗?例如,我不知道值应该如何填充,因为您总是访问它的第一个字节,参数也是如此。
As Mark B answers, I heavily suggest the use of library code to parse arguments. It might look easy, but there are actually gazillions of corner cases to handle.
作为Mark B的回答,我强烈建议使用库代码来解析参数。这看起来可能很容易,但实际上有无数的角落案件需要处理。
Your code looks like C. Are you really willing to use C++ constructs ? String processing is really different in C and in C++.
您的代码看起来像C,您真的愿意使用C++构造吗?字符串处理在C和C++中是非常不同的。
value[256]
cries for buffer overflow.
值[256]需要缓冲区溢出。
Did you consider boost::program_options
or if you can't use boost, getopt_long
?
您是否考虑过Boost::Program_Options或如果不能使用Boost,则使用getopt_long?
I've leveraged TCLAP ( Templatized C++ Command Line Parser Library ) in many C++ based command line apps and been very happy with it, but it might not give you all the flexibility to read the parameters in the format you are looking at, but still worth a look ,boost::program_options is a good suggestion also.
我在许多基于C++的命令行应用程序中利用了TCLAP(模板化C++命令行解析器库),并对它非常满意,但它可能不会给您提供以您正在查看的格式读取参数的所有灵活性,但仍然值得一看,Boost::Program_Options也是一个很好的建议。
You can do this a lot more transparently with std::string
and functions like find_first_of
, splitting off the different parts and have the nice bonus that each time a find function returns std::string::npos
, you know you've got an invalid argument.
使用std::string和诸如find_first_of这样的函数可以更加透明地完成这项工作,它们分离了不同的部分,并且每次Find函数返回std::字符串::NPOS时,您都知道您得到了一个无效参数。
I'd advise you to use the standard C library for argument parsing : there is a premade function called getopt for that.
我建议您使用标准的C库进行参数解析:有一个预制的函数,名为getopt。
*value = *( text );
This line only writes one character.
*VALUE=*(文本);此行只写一个字符。
Just use the flag library in coost.
只要使用Coost中的FLAG库即可。
// xx.cc
#include "co/flag.h"
#include "co/cout.h"
DEF_bool(x, false, "x");
DEF_uint32(u, 0, "xxx");
DEF_string(s, "", "xx");
int main(int argc, char** argv) {
flag::parse(argc, argv);
cout << "x: " << FLG_x << '\n';
cout << "u: " << FLG_u << '\n';
cout << FLG_s << "|" << FLG_s.size() << '\n';
return 0;
}
Define flags with DEF_xxx macros, and call flag::parse(argc,argv) at the beginning of the main function.
使用DEF_xxx宏定义标志,并在Main函数的开头调用FLAG::Parse(argc,argv)。
Build the above code as xx, run it as follow:
以xx身份构建上述代码,按如下方式运行:
./xx
./xx -x=true -u=77 -s="hello world"
./xx -x -u 88 -s kkk
更多回答
This is probably a good answer as long as you don't have to include a thousand other boost files as well.
这可能是一个很好的答案,只要您不需要包括一千个其他的Boost文件。
getopt is not a part of the standard C library. It's a part of the POSIX standard though.
Getopt不是标准C库的一部分。不过,它是POSIX标准的一部分。
我是一名优秀的程序员,十分优秀!