Я пытаюсь написать функцию для анализа аргументов командной строки. Это объявление функции:

void parse(int, char const **);

На всякий случай я также попытался (const char)**, const char ** и cchar **, используя typedef const char cchar. Однако все они (как и ожидалось, поскольку все они должны быть идентичны) приводят к ошибке, если я передам char ** в функцию, как в:

void main(int argc, char **argv) {
    parse(argc, argv);

Я получаю ошибку от компилятора GNU error: invalid conversion from 'char**' to 'const char**', а от Clang - candidate function not viable: no known conversion from 'char **' to 'const char **' for 2nd argument.

Я видел такие решения, предложенные как объявление указателя на константный указатель на символ (const char * const *), но я не хочу, чтобы любой указатель был константным, потому что я хочу иметь возможность изменить указатель, чтобы я мог выполнять итерацию по аргумент, использующий for(; **argv; ++*argv). Как я могу объявить "неконстантный указатель на неконстантный указатель на константный символ"?

3
Dead Beetle 29 Май 2017 в 03:51

2 ответа

Лучший ответ

Самая безопасная сигнатура, которая предотвращает изменение аргументов и позволяет любой другой комбинации const вызывать функцию:

parse(int argc, char const* const* argv);

Это означает, что argv является указателем на const указатель на const char

Вы можете счастливо перебрать параметры, как это:

for(auto arg = argv + 1; *arg; ++arg)
{
    if(!std::strcmp(*arg, "--help"))
        return print_help();
    else if(!std::strcmp(*arg, "-v") || !std::strcmp(*arg, "--verbose"))
        verbose_flag = true;
    // ... etc...
}

Заметьте, что нет необходимости принимать переменную int argc, потому что массив символьных массивов завершен нулем .

Поэтому я обычно использую это:

struct config
{
    // program options and switches
};

config parse_commandline(char const* const* argv);
5
Galik 29 Май 2017 в 01:23

Функция должна быть объявлена как:

void parse(int, char const * const *);

В C ++ char ** может неявно добавлять const на всех глубинах указателя, поэтому вы можете назвать его parse(argc, argv).

В C const может быть добавлено только на первой глубине указателя (это дефект дизайна в языке). Вот специальная тема. Поэтому, к сожалению, вы должны вызывать функцию как: parse(argc, (char const * const *)argv);.

7
M.M 29 Май 2017 в 01:08