【问题标题】:Defining Command Line Arguments w/ functions使用函数定义命令行参数
【发布时间】:2016-02-01 18:31:54
【问题描述】:

以下代码:

#include<stdio.h>

void main(int argc, char * argv[]) {
   int i, n, sum = 0;

   if (argc == 1) {
      printf("You have forgot to type numbers.");
      exit(1);
   }

   printf("The sum is: ");
   ///for (i = 1; i < argc; i++)
      ///sum = sum + atoi(argv[i]);

      for(i = 0; i < argc; i++)
        {
            n = atoi(argv[i]);
            sum += n;
        }
   printf("%d", sum);
}

在命令行中给出总和,例如,如果在提示符下输入“program.exe 23 23 32”,输出将是“总和为:68”。

我想将求和逻辑分开,使其成为自己的函数,然后在提示符下我希望能够键入“program.exe -sum 23 23 32”以获得相同的结果。

【问题讨论】:

  • main() 返回int。你有什么问题?
  • 使用像-sum 这样的参数并不意味着它有自己的功能。你只需要解析参数并采取相应的行动。
  • 好的。我明白你的意思了。我想我有点卡在解析部分,即我们如何定义参数。第一个是程序名称,第二个是函数,第三个参数是适当的数据,在这种情况下是一堆整数。

标签: c parsing command-line-arguments


【解决方案1】:

在很多 C 代码中,我们使用捷径来简化解析。例如,假设我们知道我们只有 2 个运算符选择:sumproduct。然后我们知道第一个参数必须是-sum-product。我们可以通过检查- 后跟sp 来简化解析。

至于抽象实际操作符,在这种情况下,只检查在命令行上选择了哪个操作符,然后在此基础上应用 +=*= 可能更有效。

这是一些工作代码:

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char * argv[]) {
    int n;
    int result;
    int i = 1;
    char operator;

    // parse -sum or -product
    if (argv[i] && argv[i][0] == '-') {
        // we take a shortcut and just look at the first letter
        char firstLetter = argv[i][1];
        if (firstLetter == 's') {
            // using sum
            operator = '+';
            result = 0; // additive identity
        }
        else if (firstLetter == 'p') {
            // using product
            operator = '*';
            result = 1; // multiplicative identity;
        }
        else {
            printf("Unknown option: %s\n", argv[i]);
            exit(1);
        }
        // move on to the next argument
        i++;
    }
    else {
        printf("Please specify an operation (-sum or -product)\n");
        exit(1);
    }

    if (!argv[i]) {
        printf("You have forgot to type numbers.\n");
        exit(1);
    }

    for(; argv[i]; i++) {
        n = atoi(argv[i]);
        if (operator == '+') {
            result += n;
        }
        else { // if (operator == '*')
            result *= n;
        }
    }

    printf("The result is: %d\n", result);

    return 0;
}

请注意,result 的初始值因选择的操作而异。

上面的代码没有使用argc,而是利用了argv 数组以空值结尾的事实。换句话说,如果您有 3 个参数(或 argc=4),那么 argv[3] 将是 NULL(相当于 0 或 false)。

请注意,如果您打开优化,那么任何体面的 C 编译器都会将测试移出循环,因此它实际上只检查选择了哪个operator。 (这很容易通过查看生成的汇编代码来验证。)

【讨论】:

    【解决方案2】:

    在我看来,您实际上并不需要- 前面的sum;第一个参数应该是一个简单的字符串:

    program.exe sum 1 3 5 9
    

    无论你是否保留破折号,你都可以简单地安排将一个指向参数列表其余部分的指针传递给一个函数,该函数期望:

    int sum(int numc, char **numv)
    

    它返回在数字向量numv 中表示为字符串的numc 数字的总和。你可以很容易地调用它:

    int rv = sum(argc - 2, argv + 2);
    

    在您确定 sum 是要调用的函数之后。并且你可以拥有这些函数的集合。

    如果您遇到过函数指针,您可以自己创建一个名称数组(用户将在命令行上键入)和函数​​指针(指向相应的函数)。然后,您只需查找用户在数组中键入的名称并调用相应的函数。不过,这对你来说可能仍然是未来。

    【讨论】:

      【解决方案3】:

      我找到了thisthis。后者包含一些有用的代码,几乎完全符合您的要求。他们的示例需要知道使用了多少参数(sum 函数中的 for 循环包含 i &lt; 5),但可能有一种解决方法。

      man 3 stdarg 也应该有帮助。

      【讨论】:

      • 我不认为 va_arg 是 OP 在这里寻找的。使用数组更有意义(尤其是因为 argv 已经是要求和的值的数组)。
      猜你喜欢
      • 2011-06-14
      • 2014-03-17
      • 2011-01-07
      • 1970-01-01
      • 2022-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-20
      相关资源
      最近更新 更多