【问题标题】:Building an arglist for Unix program为 Unix 程序构建一个 arglist
【发布时间】:2011-12-15 06:47:16
【问题描述】:

为了根据用户输入多次执行程序,我需要改变发送到执行函数的 arglist 数组。在大多数情况下,我让它工作,除了设置最终标志来表示从信息增益、第一指数和基尼系数中使用哪个分割函数

该程序具有三种不同的拆分功能,可根据训练和测试数据集创建决策树。我设置了 arglist 来模仿传统的 CLI 输入,所以这些是有效的输入:

./decision voting 5

./decision -train voting-train-1 -test voting-test-1 -out voting.out -[i, s, g]

第一个命令的作用是对所有从 1 到 5 的投票-- 文件执行所有三个拆分函数,而第二个命令对单个数据集执行此操作。

我有一个根据迭代构建的临时 arg 数组,当需要添加最终标志时,这就是我所做的:

//flag pointers
char *igFlag= "-i";
char *faFlag= "-s";
char *giFlag= "-g";

//copy temp array to specific arglist
igInput= cli;
faInput= cli;
giInput= cli;

//set information gain flag and null
igInput[7]= igFlag;
igInput[8]= '\0';

//set first attribute flag and null
faInput[7]= faFlag;
faInput[8]= '\0';

//set gini coefficient and null
giInput[7]= giFlag;
giInput[8]= '\0';   

这里的问题是,当faInput[7]= faFlag 执行时,它会更改igInput[7] 以匹配,然后当giInput[7]= giFlag 执行时,所有三个数组都有匹配的[7] 指针。

我在对整数数组使用相同的临时指针时遇到了类似的问题,但是通过使用不同命名的变量来解决这个问题。即使我有彼此无关的不同变量,也会发生此问题。

已解决

为了响应 AusCBloke 的请求,了解我是如何解决这个问题的,来吧。

首先,我决定不需要多个输入字符串,只需要修改最后一个槽的那个。所以我剪掉了两个 xxInput 字符串,只使用了一个。

我最终需要更多的标志,而不是重复的代码,我创建了一个 char flag[5] 包含要使用的标志。然后从 for 循环内部调用它们,其中使用的标志是当前索引值。

总而言之,这种方法最终删除了大约 30 行不需要的代码。

【问题讨论】:

  • 你考虑过使用getopt和getopt_long吗?这些是处理命令行选项的标准方法。
  • ^^ 应该是一个答案。因为它答案。
  • 你错过了问题的重点——我不是在问解析命令行输入,而是在构建它们。 getopt 解析 CLI,但我看不出它适合这里
  • 是的,我刚刚意识到这一点。如果您在更改标志后exec(或您调用的任何内容),您可以保持与您所拥有的代码相似的代码,您不一定需要复制整个cli 以重用它。编辑了我的帖子。
  • 你最终是如何解决你的问题的?

标签: c unix command-line-arguments


【解决方案1】:

这里的问题是当faInput[7]= faFlag 执行时,它会改变 igInput[7] 匹配,然后当 giInput[7]= giFlag 被执行时, 所有三个数组都有匹配的 [7] 指针。

//copy temp array to specific arglist
igInput= cli;
faInput= cli;
giInput= cli;

您没有复制cli,您将每个char * 设置为指向cli。所以igInput[7] == faInput[7] == giInput[7] == cli[7]

如果不使用 meagar 的 getopt 建议,请为 ig/fa/gaInputmemcpy cli 分配内存。

编辑:哦,等等,您是在尝试将这些参数传递给其他东西,而不是读入它们? cli 是不是有点像 argv?如果确实如此,并且clichar ** 那么你可以保持它与你拥有它的方式相似,即:

cli[8] = NULL;

cli[7] = igFlag;
execv(cli[0], cli);

cli[7] = faFlag;
execv(cli[0], cli);

cli[7] = giFlag;
execv(cli[0], cli);

【讨论】:

  • 或者,因为这是 Unix,而不是 malloc()ating 和 memcpy()ing,只是 strdup()。
  • 哦,是的,老strdup,如果他想复制整个cli,他可以这样做。干得好。
【解决方案2】:

你把一些微不足道的事情变成了一场噩梦。我的理解是,您想要运行命令 3 次,使用 -i-s-g,具体取决于迭代。这样做:

char opt[] = "-i", *cmd[] = {
    "decision", "-train", "voting-train-1", "-test", "voting-test-1",
    "-out", "voting.out", opt, 0
};
/* use first command line */
opt[1] = 's';
/* use second command line */
ops[1] = 'g';
/* use third command line */

【讨论】:

  • 我选择你的作为答案,因为你最接近我的最终解决方案。请参阅我的编辑以进行澄清
【解决方案3】:

您的代码不会将cli 数组复制到各种输入变量。它将所有三个输入指针设置为指向cli 数组。由于igInputfaInputgiInput 都指向同一个地方,更改faInput[7] 似乎也会修改giInput[7],因为它们都指向相同的基础数据。您需要使用memcpy 来复制数组数据。但是你真的应该使用getopt 来处理你的参数,正如@meagar 所建议的那样。

//copy temp array to specific arglist
igInput= cli;
faInput= cli;
giInput= cli;

【讨论】:

    猜你喜欢
    • 2012-02-01
    • 1970-01-01
    • 2011-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-03
    • 1970-01-01
    相关资源
    最近更新 更多