#c #linux #command-line-arguments
Вопрос:
Обязательный полный нуб здесь.
Я создаю простую программу на языке Си, которая считывает некоторые переменные из файла с помощью простой функции. Однако я пытаюсь добиться того, чтобы любой, кто вызывает программу, мог переопределить значения, считанные из файла, если это указано в аргументах командной строки. Я бы хотел иметь что-то подобное:
char* filename;
int number;
...
readConfig(filename, number, ...);
if (argc > 1) {
// Check if the variables were in the args here, in some way
strcpy(filename, args[??]);
number = atoi(args[??]);
}
Я бы хотел, чтобы программа называлась так
program -filename="path/to/file.txt" -number=3
Я понял, что могу просто маркировать каждый аргумент и сопоставлять его с каждой назначаемой переменной, а остальные отбрасывать, но я почти уверен, что есть более элегантный способ сделать это (возможно, с помощью getopts?)
Большое вам спасибо за вашу помощь.
Ответ №1:
Я нашел это на geeksforgeeks:
#include <stdio.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int opt;
// put ':' in the starting of the
// string so that program can
//distinguish between '?' and ':'
while((opt = getopt(argc, argv, ":if:lrx")) != -1)
{
switch(opt)
{
case 'i':
case 'l':
case 'r':
printf("option: %cn", opt);
break;
case 'f':
printf("filename: %sn", optarg);
break;
case ':':
printf("option needs a valuen");
break;
case '?':
printf("unknown option: %cn", optopt);
break;
}
}
// optind is for the extra arguments
// which are not parsed
for(; optind < argc; optind ){
printf("extra arguments: %sn", argv[optind]);
}
return 0;
}
Итак, когда вы проходите -f
, вам нужно также передать имя файла, например: ./args -f filename
в нем будет написано:
$ ./a.out -f file.txt
filename: file.txt
Когда вы пройдете -i
, -l
, или -r
, или -ilr
, он скажет:
$ ./a.out -ilr
option: i
option: l
option: r
Если вы передадите -f
, но без имени файла, он скажет, что параметр нуждается в аргументе. Все остальное будет напечатано с дополнительными аргументами
Таким образом, с его помощью вы можете добавлять опции для getopts, добавлять новый регистр, делать что-то вроде: getopts(argc, argv, ":fn:")
— f имя файла, -n число, довольно просто
Комментарии:
1. Это хорошее решение; имейте в виду, что оно использует расширения POSIX (которые довольно часто поддерживаются).