如何将命令行参数读作整数而不是字符串?

时间:2017-02-12 10:40:30

标签: c argv

对不起我的问题,我知道有很多类似的但我没有找到任何简单的帮助我。

我已经开始用C编码并尝试解决一个简单的练习:从命令行读取一个整数数组,使用函数array_sum和打印结果对元素求和。 (3个元素的输入示例数组:3 0 1 2)

int array_sum(int *array,  size_t size);
int main(int argc, char **argv){
    int sum=array_sum(argv, argc);
    printf("array_sum: %i\n", sum);
    return 0;
}

我的问题是argv是一个char数组,函数想要一个整数数组。 我应该在新的int数组中逐个转换元素吗?有更好的方法吗?

4 个答案:

答案 0 :(得分:5)

argv是指向C字符串的指针数组。您需要首先将字符串转换为整数。你可以这样做:

int array_sum(int *array,  size_t size);
int main(int argc, char **argv){
    int *num_arr = malloc((argc - 1) * sizeof *num_arr);

    for (int i = 0; i < argc - 1; ++i)
      num_arr[i] = atoi(argv[i+1]);

    int sum = array_sum(num_arr, argc - 1);
    printf("array_sum: %i\n", sum);

    free(num_arr);
    return 0;
}

使main中的代码更短的唯一方法是将转换循环移动到一个单独的函数中,该函数返回malloc ed指针。

答案 1 :(得分:2)

在您的代码中,char *argv[]是从命令行提供的char*指针数组。要转换提供的数字,您可以使用以下内容:

  • atoi(),它将字符串争用转换为整数类型。
  • strtol(),在给定基础的情况下将字符串的初始部分转换为long int
  • C99中的其他特殊功能,其中很多内容在此post中进行了描述。

由于atoi()没有错误检查,因此最好使用strtol(),这允许进行大量错误检查。

您应该将这些转换后的数字存储在一个动态分配的int*指针中,该指针需要使用malloc()在堆上进行分配,这是@StoryTeller在他的回答中提出的。您也可以在堆栈上声明一个数组,例如int arr[n]。如果要在函数中返回此数组,则会出现问题,这是不可能的。在这种情况下使用指针将允许更多的抽象灵活性。

  

malloc()在堆上分配内存块,并返回一个void*指针。

注意: malloc()应始终进行检查,因为它可以返回NULL。你最后还需要free()这个指针。

以下是一些示例代码:

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

#define BASE 10

/* Guessed that your function would look like this */
int array_sum(int *array, size_t size) {
    int sum = 0;

    for (size_t i = 0; i < size; i++) {
        sum += array[i];
    }

    return sum;
}

int main(int argc, char *argv[]) {
    int *arr = NULL;
    char *endptr = NULL;
    int check, sum;
    size_t ndigits = (size_t)argc-1;

    /* allocate pointer */
    arr = malloc(ndigits * sizeof *arr);
    if (arr == NULL) {
        fprintf(stderr, "Cannot %zu spaces for integers\n", ndigits);
        exit(EXIT_FAILURE);
    }

    for (size_t i = 0; i < ndigits; i++) {

        /* sufficient checking for strtol(), more can possibly be added here */
        check = strtol(argv[i+1], &endptr, BASE);
        if (endptr != argv[i+1] && *endptr == '\0') {
            arr[i] = check;
        }
    }

    sum = array_sum(arr, ndigits);

    printf("array_sum: %d\n", sum);

    /* pointer is free'd */
    free(arr);
    arr = NULL;

    return 0;
}

示例输入:

$ gcc -Wall -Wextra -std=c99 -o sumcommands sumcommmands.c
$ ./sumcommands 3 2 1

输出:

array_sum: 6

注意:您可以对Man page上的strtol()使用更多错误检查。

答案 2 :(得分:1)

为什么需要将int数组作为参数传递给函数?只需执行此操作即可创建额外的int数组:

int array_sum(char **argv, int argc){
  int sum = 0;
  for(int i = 0;i < argc - 1;i++){
    sum += atoi(argv[i])
  }
  return sum;
}

答案 3 :(得分:0)

您可以使用atoi()函数将 char **数组转换为** int 。我在这里看到的是你输入的每个整数都转换为字符串而不是字符串