C++ 如何通过命令行参数传递参数

3
我有一个需要接受多个命令行参数的程序。我已经到了需要设置它来接受第n个参数的阶段,该参数指定最大和最小长度将最终被打印的字符串。基本上输入可能是这样的:
-a -n7,7 -i // with -a and -i being other arguments

我可以挑选出单个参数,但不确定如何提取最大和最小值。我已经尝试过(见下文),但每当我尝试使用变量minimum和maximum时,就会出现运行时错误。谢谢各位。

int c;
while ((c = getopt(argc, argv, ":wpsaevin")) != -1) {
    switch (c) {
        case 'w': // pattern matches whole word
            mode = WHOLE;
            break;
        case 'p': // pattern matches prefix
            mode = PREFIX;
            break;
        case 'a': // pattern matches anywhere
            mode = ANYWHERE;
            break;
        case 's': // pattern matches suffix
            mode = SUFFIX;
            break;
        case 'e': // pattern matches anywhere
            mode = EMBEDDED;
            break;
        case 'v': // reverse sense of match
            reverse_match = true;
            break;
        case 'i': // ignore case of pattern
            ignore_case = true;
            break;
        case 'n': //Specifies word length
            length_spec = true;
            cin >> minimum >> maximum;
            if (minimum == 0 && maximum == 0) { //no word limit
                length_spec = false;
            } else if (maximum == 0) {
                maximum = 100;
            }
            break;
    }
}
argc -= optind;
argv += optind;

1
我知道不是每个人都想下载boost,但我必须说boost_program_options会使这个过程变得更加容易、多功能且减少错误,如果您不介意的话,我可以发布一个带有该选项的答案。 - aaronman
2
cin 从控制台读取,这几乎肯定不是您想要的。如果 minimummaximum-n 后从命令行传入,则可以从 argv[whatever] 获取它们。 - Pete Becker
哈哈,每当我有问题时,人们总是告诉我有更简单的方法来解决它。不幸的是,我大部分工作都是为了那些规定了我们必须按照特定方式完成的任务。 - user2773084
2个回答

3

从这个页面

这个变量由 getopt 设置为指向选项参数的值,对于那些接受参数的选项。

case 'n': //Specifies word length
            length_spec = true;
            char *cvalue = optarg;
            // TODO: Split cvalue by delimiter
            // to obtain minimum and maximum
            if (minimum == 0 && maximum == 0) { //no word limit
                length_spec = false;
            } else if (maximum == 0) {
                maximum = 100;
            }
            break;

并且一个字符串分割的例子:

#include <iostream>
#include <string>
#include <algorithm>

int
main()
{
  const char* test = "1000,2000";
  std::string str = std::string(test);
  auto find = std::find(str.begin(), str.end(), ',');
  std::string first = std::string(str.begin(), find);
  std::string second = std::string(find+1,str.end());
  std::cout << first << " " << second;
  // 1000 2000
}

编辑

参考链接

如果您能使用C++11,请考虑使用std::stoi,如下所示:

  int first_int = std::stoi( first );
  int second_int = std::stoi ( second );

如果没有,尝试这个:
  std::replace(str.begin(), str.end(), ',', ' ');
  std::istringstream ss(str);
  ss >> first_int;
  ss >> second_int;
  std::cout << first_int << " " << second_int << std::endl;

我会把atoi作为最后的选择。

一个天真的实现可能看起来像这样(使用时自担风险):

int convert(std::string s)
{
    int size = s.size();
    int exp = size - 1;
    int result = 0;
    for (int i = 0; i < size; i++)
    {
        char c = s[i];
        result += (int)(c - '0') * std::pow(10, exp--);
    }
    return result;
}

谢谢。但我觉得我不太确定如何正确地组合这些示例。我尝试使用optarg读取字符串,使用分隔符将其拆分,然后使用'atoi'将两个部分都转换为int。我收到了错误消息,说find没有命名类型,而atoi无法转换,等等。 - user2773084
谢谢。我会试一下的。 - user2773084

0
你可以像@aaronman之前建议的那样使用Boost库程序选项

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接