0

The parameter to main char* argv[] decays to char**, which is unfortunate, because it cannot be used with std::begin which only accepts arrays. The only workaround I see is to use a variable length array which is undesirable.

#include <iostream>

int main(int argc, char* argv[])
{
    char* _argv[argc];
    for (int i = 0; i < argc; ++i)
        _argv[i] = argv[i];

    for (arg : _argv)
    {
        std::cout << arg << " ";
    }
    return 0;
}

Desirably I want something like: char* _argv[] = { ... };

2
  • 6
    In fact, you don't even have array to pointer decay. argv really is char**. But what problem re you string to solve? Commented Oct 7, 2014 at 8:43
  • 1
    char* _argv[argc]; is not standard C++, since there are no variable length arrays in C++. Commented Oct 7, 2014 at 8:54

3 Answers 3

6

That is not possible, since the signature of main is fixed. You can copy the elements to a vector using:

std::vector<std::string> args {argv, argv + argc};

Then you can use std::begin on args

Sign up to request clarification or add additional context in comments.

Comments

5

You can define a simple class wrapper to give you begin() and end().

struct Args {
    int argc_;
    char **argv_;
    Args (int argc, char *argv[]) : argc_(argc), argv_(argv) {}
    char ** begin () { return argv_; }
    char ** end () { return argv_ + argc_; }
};

int main(int argc, char *argv[]) {
    for (auto s : Args(argc, argv)) {
        std::cout << s << '\n';
    }
    return 0;
}

Comments

3

The only workaround I see is to use a variable length array which is undesirable.

The only workaround for what exactly? There is no problem. If you actually need an array of strings, use a vector as shown in TNAs answer; I doubt you need to modify the parameters though.
If you just need to iterate through it, there is no need to copy all the pointers.

for (auto str : boost::make_iterator_range(argv, argv + argc))
    std::cout << str;

Or

for (auto ptr = argv; ptr != argv + argc; ++ptr)
    std::cout << *ptr << '\n';

The parameter to main char* argv[] decays to char**, which is unfortunate, because it cannot be used with std::begin which only accepts arrays.

There is no other way. The amount of command line parameters is not known at compile time, and this method of passing them (instead of using two pointers-to-pointers) is historically motivated.

1 Comment

Thank you for a solution that has no memory allocations.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.