2017-02-12 8 views
1

Извините за мой вопрос, я знаю, что есть много аналогий, но я не нашел ничего, что было бы простым enaugh, чтобы помочь мне.Как читать аргументы командной строки как целые числа вместо строк?

Я начал кодирование на 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 является массивом символов и функция хочет целочисленный массив. Должен ли я преобразовывать элементы по одному в новый массив int? Есть ли лучшие способы?

+2

'Должен ли я преобразовывать элементы один за другим в новый массив int?' Да. –

+0

@adev 3 0 1 2 - это массив из четырех элементов, не так ли? –

+0

@ VladfromMoscow первый элемент был рассчитан на длину массива – adev

ответ

4

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 ред.

+0

Спасибо, нет необходимости использовать malloc, потому что я знаю длину массива – adev

+1

@adev - Если вы ссылаетесь на 'argc', тогда длина массива является переменной, и вы наверняка нужен 'malloc'. Хотя вы можете уйти с массивом переменной длины, если 'argc' не« слишком большой ». – StoryTeller

+0

Вызов 'array_sum (argv, argc)' не будет компилироваться. Предположительно вы намеревались 'array_sum (num_arr, (size_t) argc-1)'. – Peter

0

Зачем вам нужно передать массив 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; 
} 
+0

Правда, но это только жизнеспособно, если требование использования 'array_sum' может быть ослаблено – StoryTeller

+0

yes @StoryTeller, я должен использовать предоставленную функцию. Цель упражнений, я думаю, это взаимодействие – adev

0

Вы можете использовать функцию atoi() для преобразования полукокса ** массив ** Int. то, что я вижу здесь, - это каждое целое число, которое вы вводите, преобразуется в строка, а не char.

2

В вашем коде char *argv[] представляет собой массив указателей char*, предоставленных из командной строки. Для того, чтобы преобразовать число поставки, вы можете использовать следующее:

  • atoi(), который преобразует строку arguement к целому типу.
  • Или 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 

Примечание: Вы можете использовать больше проверку ошибок для strtol() на Man page.

+0

спасибо за объяснение :) – adev

 Смежные вопросы

  • Нет связанных вопросов^_^