adev
adev

Reputation: 23

How to read command-line arguments as integers instead of strings?

Sorry for my question, I know there are a lot similars but I didn't found any that is simple enaugh to help me.

I've started coding in C and try to solve a simple exercise: Read an integers array from command line, sum the elements using the function array_sum and print result. (input example array of 3 elements: 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;
}

my problem is that argv is a char array and the function want an integer array. Should I convert elements one by one in a new int array? There are better ways?

Upvotes: 1

Views: 2474

Answers (4)

RoadRunner
RoadRunner

Reputation: 26315

In your code, char *argv[] is an array of char* pointers supplied from the command line. In order to convert the numbers supplied, you can use the following:

  • atoi(), which converts string arguement to an integer type.
  • Or strtol(), which converts the initial part of a string to a long int, given a base.
  • Other special functions from C99, alot of which are described in this post.

Since atoi() has no error checking, it is best to use strtol(), which allows extensive error checking.

You should store these converted numbers in a dynamically allocated int* pointer, which will need to be allocated on the heap using malloc(), which was suggested by @StoryTeller in his answer. You could also just declare an array on the stack, such as int arr[n]. The problem arises when you want to return this array in a function, which is not possible. Using a pointer in this case would allow more flexibility for abstraction.

malloc()allocates block of memory on the heap, and returns a void* pointer to it.

Note: malloc() should always be checked, as it can return NULL. You need to also free() this pointer at the end.

Here is some example code:

#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;
}

Example input:

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

Output:

array_sum: 6

Note: You can use more error checking for strtol() on the Man page.

Upvotes: 2

argv is an array of pointers to C strings. You need to convert the strings into integers first. You can do something like this:

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;
}

The only way to make the code in main shorter is by moving the conversion loop into a separate function that returns the malloced pointer.

Upvotes: 5

Jarvis
Jarvis

Reputation: 8564

Why do you need to pass an int array as argument to the function ? No need to create an extra int array when you can simply do this :

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

Upvotes: 1

Prithvi Raj
Prithvi Raj

Reputation: 1961

You can use atoi() function to convert char ** array to **int . what i see here is each integer you type is converting into string rather than char.

Upvotes: 0

Related Questions