[英]Custom Command Line Parameters
I have a problem with command line parameters. 我的命令行参数有问题。 I finished the program so I can start it like this from command line:
我完成了程序,所以我可以从命令行启动它:
program.exe test.txt copy_test.txt
Basically, my program does the following : 基本上,我的程序执行以下操作:
BUT (always that but?!), I should start the program from command line like this: 但是(总是这样但是?!),我应该从命令行启动程序,如下所示:
program.exe -input=test.txt -output=copy_test.txt
And I don't know how to do that. 我不知道该怎么做。 I researched, but I didn't find any help :(
我研究过,但我没有找到任何帮助:(
Please respond. 请回复。
#include <string>
#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
int main ( int argc, char* argv[])
{
ifstream in(argv[1]);
ofstream out(argv[2]);
vector <string> sV;
string line;
while (in >> line)
sV.push_back(line);
for ( int i = 0; i < sV.size(); i++)
sort ( sV.begin(), sV.end () );
for ( int i = 0; i < sV.size(); i++)
out << sV[i] << endl;
cin.get();
return 0;
}
You should parse main
's argv
arguments in order to check whether they start by -input
, -output
etc etc. 你应该解析
main
的argv
参数,以便检查它们是否以-input
, -output
等开始。
Doing this from scratch is a hell, but luckily there are many useful libraries to do this, like boost.program_options 从头开始这样做是一个地狱,但幸运的是有很多有用的库可以做到这一点,比如boost.program_options
I'm a bit late to the party with this, but I'll provide an updated answer. 我有点迟到了,但我会提供一个更新的答案。 You can actually get the functionality that you want in C++ with a little work using 'getopt'.
您可以使用'getopt'实际获得C ++中所需的功能。 Using
getopt_long()
you can create either single character options (like -c
) or named options (like --input
). 使用
getopt_long()
可以创建单个字符选项(如-c
)或命名选项(如--input
)。 You can also use getopt_long_only()
which will allow you to pass named options with only a single dash. 您还可以使用
getopt_long_only()
,这将允许您只使用一个破折号传递命名选项。 See for example here or this answer . 例如,请参阅此处或此答案 。
Example 例
Here is an example that should accomplish what you're trying to do: 这是一个应该完成你要做的事情的例子:
#include <iostream>
#include <getopt.h>
#include <map>
#include <string>
int main (int argc, char** argv)
{
// Create the variables to store your parameters
std::map<std::string, std::string> input_parameters ;
input_parameters["input"] = "default_in" ; // Storage for input
input_parameters["output"] = "default_out" ; // Storage for output
// Create variables to hold your parameters
const struct option longopts[] =
{
{"input", required_argument, 0, 'i'},
{"output", required_argument, 0, 'o'},
{0,0,0,0} // This tells getopt that this is the end
};
// Some parameters for getopt_long
int c(0);
// Get the options from the command line
while (c != -1) {
int option_index(-1) ;
// Read the next command line option
// Note here that the ':' after the 'i' and 'o' denotes that
// it requires an argument
c = getopt_long(argc, argv, "i:o:", longopts, &option_index) ;
// If the option is valid, fill the corresponding value
if ((c>0)&&(option_index>=0)) {
std::cout << option_index << std::endl;
input_parameters[longopts[option_index].name] = optarg ;
}
switch (c) {
case 'i':
// Fill input option
input_parameters["input"] = optarg ;
case 'o':
// Fill output option
input_parameters["output"] = optarg ;
case '?':
// getopt_long printed an error message
break ;
}
}
std::cout << "input = " << input_parameters["input"] << std::endl;
std::cout << "output = " << input_parameters["output"] << std::endl;
return 0 ;
}
Note that here, you would run this leaving a space between the parameter and the value you want to pass to it. 请注意,在这里,您将运行此参数,在参数和要传递给它的值之间留一个空格。 This will produce the following:
这将产生以下结果:
$ ./myscript --input inputfile.txt --output outputfile.txt
input = inputfile.txt
output = outputfile.txt
or 要么
$ ./myscript -i inputfile.txt -o outpufile.txt
input = inputfile.txt
output = outputfile.txt
You can also use --input
and -i
interchangeably (similarly with --output
and -o
). 您也可以交替使用
--input
和-i
(与--output
和-o
类似)。
Begin shameless plug (my own CLOptions code that is built around getopt) 开始无耻的插件 (我自己的CLOptions代码是围绕getopt构建的)
I was actually a little disgruntled with the amount of work it took to get the full blown functionality of getopt with parameters that could be either boolean, double, int, or string. 实际上,我对使用boopt,double,int或string参数获取getopt的完整功能所花费的工作量有点不满。 I also had to create an entirely new implementation in EVERY PROJECT!
我还必须在每个项目中创建一个全新的实现! So, instead I put together a quick class called "CLOptions" so I could
#include "CLOptions.h"
in my code (everything is in a single file) and now I only need one line to define each additional option. 所以,我把一个名为“CLOptions”的快速类放在一起,这样我就可以在我的代码中
#include "CLOptions.h"
(一切都在一个文件中),现在我只需要一行来定义每个附加选项。 It also creates the -h
or -help
options for printing help information for you! 它还会为您打印帮助信息的
-h
或-help
选项! It includes functionality for getting each parameter as either a bool, double, int, or string depending on how you define each parameter. 它包括将每个参数作为bool,double,int或string的功能,具体取决于您定义每个参数的方式。 You can take a look at it on GitHub here with an example of how the above method could be implemented .
您可以在GitHub上查看它,并举例说明如何实现上述方法 。 Note that the class is C++11 and will require the
-std=c++11
at compile time (although if someone asks, I can try and code up a C version). 请注意,该类是C ++ 11,并且在编译时需要
-std=c++11
(尽管如果有人问,我可以尝试编写C版本)。
Although I haven't tried them, there's also a host of other command line programs that have been designed by other people to solve this problem (for example options or dropt ). 虽然我还没有尝试过,但是还有许多其他命令行程序由其他人设计来解决这个问题(例如选项或dropt )。 You can probably find them by googling around.
你可以通过谷歌搜索找到它们。
You could eliminate the need for advanced users to have to type unnecessary text each time they run your program and instead offer a -help switch that displays usage. 您可以消除高级用户每次运行程序时必须键入不必要的文本的需要,而是提供显示用法的-help开关。
This is generally the approach most command line programs take, and is the reason why many command line enthusiasts appreciate the simplicity and power of the command line. 这通常是大多数命令行程序采用的方法,也是许多命令行爱好者欣赏命令行的简单性和强大功能的原因。
Another option would be to offer both methods, as some users may prefer the longer method. 另一种选择是提供两种方法,因为一些用户可能更喜欢更长的方法。
Well, with your new format arguments, you can't just pass them as-is to the stream constructors. 好吧,使用新的格式参数,您不能只是按原样将它们传递给流构造函数。
You will have to check if they start with a specific string, such as with strncmp
and then pass the address of the relevant bit such as argv[1]+8
for the input type. 您必须检查它们是否以特定字符串开头,例如使用
strncmp
,然后为输入类型传递相关位的地址,例如argv[1]+8
。
Since you're providing --input=
type prefixes, you may also want to handle the possibility that they may be in the other order as well. 由于您提供了
--input=
type前缀,因此您可能还希望处理它们可能处于其他顺序的可能性。
For example, you can replace: 例如,您可以替换:
int main (int argc, char* argv[]) {
ifstream in(argv[1]);
ofstream out(argv[2]);
with something like: 有类似的东西:
int main (int argc, char* argv[]) {
char *infile = 0;
char *outfile = 0;
for (int i = 1; i < argc; i++) {
if (strncmp (argv[i], "--input=", 8) == 0) {
infile = argv[i] + 8;
} else {
if (strncmp (argv[i], "--output=", 9) == 0) {
outfile = argv[i] + 9;
} else {
std::cerr << "Invalid argument [" << argv[i] << "]" << std::endl;
return -1;
}
}
}
if ((infile == 0) || (outfile == 0)) {
std::cerr << "Need to specify input and output file" << std::endl;
return -1;
}
ifstream in(infile);
ofstream out(outfile);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.