如何从shell传递整数向量?

时间:2016-09-09 19:02:01

标签: c++ shell

我想传递整数数组/向量作为shell参数?以下是我的最后一次尝试:

#include <iostream>
#include <vector>
#include <string>
//using namespace std;

int main(int argc, const char *argv[])
{
    char dummy;
    std::vector<int> argument(argc-1);
    std::cout<<argc<<std::endl;

    for (int i = 1; i <= argc; ++i)
    {
        dummy=*(*(argv+1)+i);
        argument[i-1]=std::stoi(dummy);
    }

    std::cout<<argument.size()<<std::endl;
    return 0;
}

我收到了错误:

  

错误:没有匹配函数来调用'stoi(char&amp;)'

有没有更简单的方法呢? 基本上运行程序为:

  

./ executable {1,2,3,4,5}

并使用这些值初始化程序中的数组/向量?

2 个答案:

答案 0 :(得分:2)

解决编译器错误是浪费时间。 OP最初使用std::string dummy;时有正确的想法,所以让我们坚持下去并弄清楚出了什么问题。

首先让我们假设4个参数:1 12 123 1234并检查4循环的范围。

for (int i = 1; i <= argc; ++i)

因为OP在1处开始循环,我假设他们知道第一个参数是执行的命令。好开始。

但是i <= argc将允许i的范围从1到5. argv在0到4之间有效。这意味着在访问argv[5]和Crom时调用了未定义的行为只知道之后会发生什么。很可能dummy加载了来自argv[5]的垃圾,而std::stoi无法将此垃圾解析为int。这只是猜测。确定未定义行为的行为是浪费时间。下次可能会有所不同。它甚至可能看起来像下次一样。

所以要做的第一件事就是摆脱界外阅读。

for (int i = 1; i < argc; ++i)

现在我们有一个范围为1到4的i,一切都在界限内。

接下来,我们可以清理

dummy=*(*(argv+1)+i);

因为我们不再需要将它装入char了。最简单的是

std::string dummy(argv[i]);

声明string dummy并将其初始化为包含一个命令行参数。这可以更快地完成吗?是的,但这很容易阅读。从简单开始,只有在不符合计划要求的情况下才能进入困境。在强制之前我将在此处进行的唯一更改是将dummy更改为更具描述性的名称。

你可以更简单

argument[i-1]=std::stoi(argv[i]);

但至少我现在更喜欢dummy方法。它具有主要的调试优势:您可以打印或使用调试器在dummy引发异常之前检查std::stoi的值,因为dummy无法转换。

结果代码:

int main(int argc, const char *argv[])
{
    std::vector<int> argument(argc-1);
    std::cout<<argc<<std::endl; 

    for (int i = 1; i < argc; ++i) 
    {
        std::string dummy(argv[i]);
        argument[i-1]=std::stoi(dummy);
    }

    std::cout<<argument.size()<<std::endl;
    return 0;
}

使用./executable 1 12 123 1234调用输出

5
4

向量中有5个输入参数和4个项,因为该命令被丢弃。

弄清楚如何处理

中的花括号
./executable {1, 2, 3, 4, 5}

我要去OP去弄清楚。

答案 1 :(得分:1)

无需简单地使用

    argument[i-1]=std::stoi(argv[i]); in place of 

    dummy=*(*(argv+1)+i);
    argument[i-1]=std::stoi(dummy);

我们知道大小为n的数组存储从位置0到位置n-1的元素。  argc是运行程序时的字符串数,包括可执行文件名,我们知道argv是字符串数组(字符序列),所以argv中的零位是可执行文件名。这就是为什么从位置i = 1开始循环,我们需要运行循环i = 1到i&lt; argc(指直到i&lt; = argc-1)

尝试以下程序

  #include <iostream>
  #include <vector>
  #include <string>
  using namespace std;

  int main(int argc, const char *argv[])
  {
  char dummy;
  std::vector<int> argument(argc-1);
  std::cout<<argc<<std::endl;

  for (int i = 1; i < argc; ++i)
  {
      //   dummy=*(*(argv+1)+i);
    // argument[i-1]=std::stoi(dummy);

     argument[i-1]=std::stoi(argv[i]);
   }

  std::cout<<argument.size()<<std::endl;

 return 0;
 }