如何在C中汇总所有命令行参数?

时间:2018-02-01 14:34:43

标签: c syntax-error command-line-arguments atoi

我有一项任务。该程序将打印C中所有命令行参数的总和。我尝试编译它编译的代码但在控制台中传递参数后抛出错误。以下是代码。

/* Printing sum of all command line arguments */
#include <stdio.h>

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

    for (counter = 1; counter <= argc; counter++) {
       sum = atoi(sum) + atoi(argv[counter]);
    }
    printf("Sum of %d command line arguments is: %d\n", argc, sum);
}

编译后输出Segmentation fault (core dumped)错误。您的经验可以解决我的问题。

以下是我编辑的代码:

/* Printing sum of all command line arguments*/
#include <stdio.h>
#include <stdlib.h> // Added this library file

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

    for (counter = 1; counter < argc; counter++) {
        // Changed the arithmetic condition
        sum = sum + atoi(argv[counter]);
        // Removed the atoi from sum variable
    }
    printf("Sum of %d command line arguments is: %d\n", argc, sum);
}

5 个答案:

答案 0 :(得分:12)

因为你正在迭代counter == argc,所以你将NULL指针传递给atoi(),这很简单,只需要依赖argv数组有{ {1}}哨兵,并执行此操作

NULL

请注意,/* Printing sum of all command line arguments*/ #include <stdlib.h> /* For `atoi()' */ #include <stdio.h> /* For `printf()' */ int main(int argc, char *argv[]) { int sum; sum = 0; for (int counter = 1; argv[counter] != NULL; ++counter) { sum += atoi(argv[counter]); } printf("Sum of %d command line arguments is: %d\n", argc, sum); } 是未定义的行为,因为atoi(sum)sum并且不是有效指针。虽然int会尝试取消引用它。另外atoi()代表 ascii到整数,而aoti()已经是一个整数,因此转换没有意义。

最后,为sum添加 stdlib.h 。我知道你没有包含它,因为我在编译器上启用了警告,它警告我atoi()是隐式定义的。 可能可以工作,但仅仅因为未定义的行为就是这样,UNDEFINED。

另外,请注意,无法知道传递的参数是否为整数,因为atoi()无法执行错误检查。您可能希望改为使用atoi()并检查所有值是否为整数。

所以...这就是你如何编写这个程序更强大的版本

strtol()

编辑:要解决this comment

例如,如果您通过#include <stdio.h> #include <stdlib.h> int main(int argc, char *argv[]) { int sum; sum = 0; for (int counter = 1; argv[counter] != NULL; ++counter) { char *endptr; sum += strtol(argv[counter], &endptr, 10); if (*endptr != '\0') { fprintf(stderr, "error: the `%d-th' argument `%s', is not a valid integer\n", counter, argv[counter]); return EXIT_FAILURE; } } printf("sum of %d command line arguments is: %d\n", argc, sum); return EXIT_SUCCESS; } 函数之一执行程序,则有可能argc == 0。在这种情况下,您必须在开始循环之前进行检查,否则exec*()将是最后一个元素之后的一个元素,即超出范围。

答案 1 :(得分:7)

指定argv[argc] 总是是空指针。你循环太多,并将这个空指针传递给atoi,导致未定义的行为

将循环条件更改为counter < argc

并且sum已经 是一个整数,您无需将其转换为atoi的整数。由于第一次迭代将零传递给atoi(sum),因此atoi 好。

答案 2 :(得分:6)

argv的最后一个元素已定义NULL,第一个元素始终是程序名称。因此,您可以将代码缩减为

#include "stdio.h"

int main(int argc, char *argv[])
{
    int sum = 0;
    for (int i = 1; argv[i]; ++i){
        sum += atoi(argv[i]);
    }
    printf("Sum of %d command line arguments is: %d\n", argc, sum);
}

在您的代码中,atoi(sum)的行为以及最终迭代中归结为argv[argc]的行为将是未定义的。

答案 3 :(得分:-2)

一个递归版本,只是为了它:)

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

int main(int argc, char **argv)
{   
    static int sum;

    if (*++argv == NULL)
        return !printf("sum: %d argc %d\n", sum, argc - 1);

    sum += atoi(*argv);
    return main(argc, argv);
}

答案 4 :(得分:-2)

/* My example. Should work, though untested. */
#include <stdio.h>

int main(int argc, char *argv[])
{
    int sum, index;    // Generally considered better form to put them on separate lines.
    sum = 0;

    if(argc > 1) {    
        for(index = 1; index < argc; index++) {
            sum += atoi(argv[index]);
        }
        printf("%d Command-line args\nSum = %d\n", argc, sum);
    } 
    else {
        printf("Not enough command-line args\n");
    }
}

请务必尽量遵守代码的特定格式样式。如果要按名称定义样式指南,请搜索样式指南。 GNU C is a good starting point。它们将使您的代码更易于阅读,更易于调试,并帮助其他人了解其中正在发生的事情。

对上述代码进行一些更正..

/* Your code with corrections */
#include "stdio.h"

int main(int argc, char *argv[])
{
   int sum=0,counter; 
   // 1. Normally you want to give each variable it's own line. Readability is important.
   // 2. Don't initialize on declaration either. Refer to my example.
   // 3. Always add spaces between operators and at the end of statements for better readability.
    for(counter=1;counter<=argc;counter++)
    {
       // 4. atoi(sum) is unneccessary as it interprets your int sum as a const char*, 
       // which as far as I can tell should just give you back it's ascii value. 
       // It might be undefined however, so I would remove it regardless.
       // 5. Your segfault issue is because you iterate over the end of the array.
       // You try to access the [argc] value of the array (remember 0-based
       // indexing means a size val is always 1 greater than the greatest index).
       // Make 'counter<=argc' into 'counter < argc'

       sum = atoi(sum) + atoi(argv[counter]);
    }
  printf("Sum of %d command line arguments is: %d\n", argc, sum);
}

atoi() documentation of a form.

预先警告,如果您在命令行中输入字符或字符串,您的代码仍将起作用,但行为将是奇怪的。 atoi()会将char转换为相应的ASCII decimal character index/value.

您还可以使用空值(argv []始终以argv [argc]中的NULL值终止)以结束迭代。我更喜欢使用提供的argc。

希望这对你有所帮助。如果您不理解我在这里发布的任何内容,请在线评论或搜索。

干杯!