繁体   English   中英

自定义命令行参数

[英]Custom Command Line Parameters

我的命令行参数有问题。 我完成了程序,所以我可以从命令行启动它:

program.exe test.txt copy_test.txt

基本上,我的程序执行以下操作:

  • 输入一些文本文件
  • 对其进行排序并复制到新的文本文件

但是(总是这样但是?!),我应该从命令行启动程序,如下所示:

program.exe -input=test.txt -output=copy_test.txt

我不知道该怎么做。 我研究过,但我没有找到任何帮助:(

请回复。

#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;
}

你应该解析mainargv参数,以便检查它们是否以-input-output等开始。

从头开始这样做是一个地狱,但幸运的是有很多有用的库可以做到这一点,比如boost.program_options

我有点迟到了,但我会提供一个更新的答案。 您可以使用'getopt'实际获得C ++中所需的功能。 使用getopt_long()可以创建单个字符选项(如-c )或命名选项(如--input )。 您还可以使用getopt_long_only() ,这将允许您只使用一个破折号传递命名选项。 例如,请参阅此处此答案

这是一个应该完成你要做的事情的例子:

#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 ;
}

请注意,在这里,您将运行此参数,在参数和要传递给它的值之间留一个空格。 这将产生以下结果:

$ ./myscript --input inputfile.txt --output outputfile.txt
input  = inputfile.txt
output = outputfile.txt

要么

$ ./myscript -i inputfile.txt -o outpufile.txt
input  = inputfile.txt
output = outputfile.txt

您也可以交替使用--input-i (与--output-o类似)。

开始无耻的插件 (我自己的CLOptions代码是围绕getopt构建的)

实际上,我对使用boopt,double,int或string参数获取getopt的完整功能所花费的工作量有点不满。 我还必须在每个项目中创建一个全新的实现! 所以,我把一个名为“CLOptions”的快速类放在一起,这样我就可以在我的代码中#include "CLOptions.h" (一切都在一个文件中),现在我只需要一行来定义每个附加选项。 它还会为您打印帮助信息的-h-help选项! 它包括将每个参数作为bool,double,int或string的功能,具体取决于您定义每个参数的方式。 您可以在GitHub上查看它,并举例说明如何实现上述方法 请注意,该类是C ++ 11,并且在编译时需要-std=c++11 (尽管如果有人问,我可以尝试编写C版本)。

虽然我还没有尝试过,但是还有许多其他命令行程序由其他人设计来解决这个问题(例如选项dropt )。 你可以通过谷歌搜索找到它们。

您可以消除高级用户每次运行程序时必须键入不必要的文本的需要,而是提供显示用法的-help开关。

这通常是大多数命令行程序采用的方法,也是许多命令行爱好者欣赏命令行的简单性和强大功能的原因。

另一种选择是提供两种方法,因为一些用户可能更喜欢更长的方法。

好吧,使用新的格式参数,您不能只是按原样将它们传递给流构造函数。

您必须检查它们是否以特定字符串开头,例如使用strncmp ,然后为输入类型传递相关位的地址,例如argv[1]+8

由于您提供了--input= type前缀,因此您可能还希望处理它们可能处于其他顺序的可能性。

例如,您可以替换:

int main (int argc, char* argv[]) {
    ifstream in(argv[1]);
    ofstream out(argv[2]);

有类似的东西:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM