【问题标题】:Taking parameters on the command line in C++在 C++ 中的命令行上获取参数
【发布时间】:2016-01-11 19:41:29
【问题描述】:

我有一个程序,它将两个 csv 文件和一个签入日期作为输入并呈现特定的输出。因此,我通常会以这种方式运行可执行文件,

./my_executable file.csv 2015-10-13

但是我的要求是让用法以这种方式表现

my_executable --input1 ./file1.csv --input2 ./file2.csv --date 2015-08-01

我该怎么做。我是否在我的代码中某处写了输入 1、输入 2 和日期。任何帮助表示赞赏。

【问题讨论】:

  • 标准 C++ 参考应该讨论main 函数的参数。也许您需要更好的参考。
  • 显然,是的,您需要写下这些词......并期望在每个之后都有相应的文件路径。

标签: c++ csv argv


【解决方案1】:

我能想到的最简单的方法:

Live On Coliru

#include <string>
#include <vector>
#include <iostream>
#include <iterator>
#include <cassert>

int main(int argc, char *raw_argv[]) {
    using namespace std;

    vector<string> const args { raw_argv+1, raw_argv+argc };

    assert(args.size() < 1 || args[0] == "--input1");
    assert(args.size() < 3 || args[2] == "--input2");

    if (args.size() > 4) {
        std::string const& csv1 = args[1];
        std::string const& csv2 = args[3];

        std::string date = args.size() > 4? args[4] : "(unspecified)";
        std::cout <<  "Arguments received: " << csv1 << ", " << csv2 << " date:" << date << "\n";
    }
}

打印例如

./test --input1 stuff.csv --input2 other.csv
Arguments received: stuff.csv, other.csv date:(unspecified)

【讨论】:

  • 添加了现场演示链接
  • 如果 NDEBUG 被定义并且用户没有传递足够的参数,这个程序会表现出未定义的行为。
  • operator[] OOB 访问是 UB。使用at
  • @elyse 哎呀。错过了。 Fixed
  • 更严肃一点:使用getoptBoost Program Options 或像here 这样的Spirit
【解决方案2】:

通常当您以这种方式给出参数时,顺序应该无关紧要,因此您必须能够以任何顺序解析参数。

这是一个可能的解决方案:

struct arguments
{
  std::string input1;
  std::string input2;
  std::string date;
};

bool parse_arguments(int argc, char** argv, arguments& args)
{
  if(argc < 7){ //or set defaults
   //print usage();//implement
   return false;
  }
  for(int i=1; i<argc;i+=2){
    string command = argv[i];
    string argument = argv[i+1];
    if(command == "--input1"){
      args.input1 = argument;
    }
    else if(command == "--input2"){
      args.input2 = argument;  
    }
    else if(command == "--date"){ 
      args.date = argument;
    }
    else{
      std::cerr<<"Unknown argument: " <<command<<std::endl;
      //print usage();
      return false;
    }
  }
  if(args.input1.empty() || args.input2.empty() || args.data.empty())
    return false; 
  return true;
}

int main(int argc, char* argv[]){
   arguments args;
   parse_arguments(argc,argv, args);
   //now you can use the struct.
   ...
}

【讨论】:

    【解决方案3】:

    这应该会给你一个启动。
    https://www.gnu.org/software/libc/manual/html_node/Argp-Example-3.html#Argp-Example-3

    或者如果您想手动处理参数。
    见:https://www.gnu.org/software/libc/manual/html_node/Program-Arguments.html#Program-Arguments

    int main(int argc, const char **argv[])
    {
      for(int i = 0; i < argc; i++) {
        std::cout << argv[i] << std::endl;
      }
      return 0;
    }
    

    【讨论】:

      【解决方案4】:

      命令行参数通过mainargument countargument list参数传递给你的程序:

      int main(int argument_count, char * argument_list[]);
      

      第一个参数是参数的数量,包括可执行文件的名称。

      第二个参数是一个 C 风格的字符串数组,一个用于命令行上的每个参数(或单词)。第一项通常是程序的名称。

      你总是可以写一个小程序来测试一下:

      #include <iostream>
      int main(int arg_count, char * arg_list[])
      {
        for (unsigned int i = 0; i < arg_count; ++arg_count)
        {
          std::cout << "Argument " << i << ": " << arg_list[i] << std::endl;
        }
        return EXIT_SUCCESS;
      }
      

      编辑 1:
      您的参数将排列为:
      参数 0:my_executable
      参数 1:--input1
      参数 2:./file1.csv
      参数 3:--input2
      参数 4:./file2.csv
      //...

      如果你想比较这些参数,那么是的,你需要输入“input1”:

      //...
      std::string arg1 = arg_list[1];
      if (arg1 == "--arg1")
      {
        //...
      }
      

      【讨论】:

      • 我了解 argc 和 argv。但是,当我尝试运行我的程序 my_app --input ./file.csv 我得到一个 -bash: my_app: command not found
      • @Antithesis 您需要将目录添加到您的 PATH 变量中。见:unix.stackexchange.com/a/26059。将可执行目录的路径附加到 PATH 中,然后您可以获得预期的行为。
      • echo $PATH 将打印“:”加入的目录路径。那 bash 如何知道在哪个目录中搜索可执行文件。由于您的可执行目录不在 PATH 中,因此找不到 bash 报告。 [或者您可以将二进制文件移动到 $PATH 中存在的目录。例如:/bin,但除非您了解自己在做什么,否则不建议这样做]
      猜你喜欢
      • 2015-12-24
      • 2021-01-05
      • 2015-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-06
      • 2014-01-18
      • 1970-01-01
      相关资源
      最近更新 更多