Работа с аргументами командной строки в Си

Как правило, программы обрабатывают данные, которые заранее не известны. Один из способов передачи данных в программу — это файлы. Но в некоторых случаях, например, когда требуется передать название файла, число или другую "короткую" информацию, использование файлов неудобно. Представьте, что для компиляции программы компилятором gcc вам нужно было бы создавать файл с именем source_to_compile и записывать в него имя файла вашей программы!

Существует возможность передачи данных при запуске программы через параметры командной строки. Например, при выполнении команды

./find_value input.txt 3.14
в программу find_value передаются два значения: input.txt и 3.14. Естественно, в программе find_value необходимо добавить специальный код для получения и использования этих значений.

Формальные параметры функции main

Прототип функции main может иметь следующий вид: int main (int argc, char * argv[]). Имена параметров могут быть какими угодно, но принято использовать argc и argv. Значение argc равно количеству параметров, указанных в командной строке, включая имя выполняемого файла. Параметр argv является массивом строк.


    /*
    ** find_value.c
    ** Пример использования аргументов командной строки. Компилировать командой
    **    gcc -o find_value find_value.c
    */

    #include <stdio.h>

    int main (int argc, char * argv[]) {
        for(int i = 0; i < argc; i++) {
            printf("Argument %d: %s\n", i, argv[i]);
        }
        return 0;
    }
    
Выполнение этой программы указанной выше командой приведет к
      Argument 0: ./find_value
      Argument 1: input.txt
      Argument 2: 3.14
    

Обработка значений

Все значения параметров являются строками. Если по смыслу значение параметра предполагается числовым, то следует использовать функции преобразования из строки в число. Например, "простые" функции atoi (ASCII to integer), atof (ASCII to double), которые не позволяют выявить ошибки во входных данных, или более надежные strtol (string to long) и strtod (string to double).


    #include <stdio.h>
    #include <stdlib.h>    /* Для функции atof. */

    int main (int argc, char * argv[]) {
        double x;
        if(argc > 1) {
            x = atof(argv[1]);
            printf("Получено действительное число x = %f\n", x);
        }

        return 0;
    }
    

Попробуйте запустить эту программу командами ./a.out, ./a.out 3.14, ./a.out xxx.

Подсказки при запуске

Если ваша программа требует при запуске наличия параметров командной строки, а они не были указаны пользователем, то в такой ситуации принято выводить на экран подсказку о допустимых командах запуска.


    #include <stdio.h>

    static void Usage(char * prog_name) {
        printf("Программу %s следует запускать следующим образом:\n", prog_name);
        printf("  %s filename x [epsilon]\n\n", prog_name);
        printf("  filename - имя входного файла\n");
        printf("  x - искомое значени имя входного файла\n");
        printf("  epsilon - точность сравнения (значение по умолчанию: 1e-5)\n");
    }

    int main (int argc, char * argv[]) {
        /* Проверим, что как минимум два аргумента (кроме имени программы!) указаны в командной строке. */
        if(argc < 3) {
            Usage(argv[0]);
            return -1;
        }
        // ...

        return 0;
    }
    
Если параметр является необязательным, то есть он может быть указан в командной строке, но его отсутсвие не является ошибкой, его название принято указывать в квадратных скобках.

Для маньяков