The vector solution proposed copies the array (the pointers only, not the strings1 - but still). Unnessary. The argv_range solution is what I would have tried, too, if I absolutely wanted to enforce a range based loop. But that produces a lot of extra code (admitted, only once, if you write it to a header file and keep it, but still).
The classic loop appears so easy to me that I allow myself just to post it, I don't consider it worth to have all this effort just to have a range based loop...
for (char** a = argv; *a; ++a)
{
// use *a, or if you don't like:
char* arg = *a;
// use arg...
}
Or, if you won't ever need the argv array afterwards any more:
for (++argv; *argv; ++argv)
{
// use *argv, or if you don't like:
char* a = *argv;
// use a...
}
There is a little difference, you might have noticed: In the first variant, I iterate over all the values, in the second, I leave out the first one (which normally is the program name we are not interested in in many cases). The other way round, for each:
for (char** a = argv + 1; *a; ++a);
for (; *argv; ++argv);
Note that all these variants profit from the fact that the strings array itself is null-pointer-terminated as well, just as any of the strings is null-character-terminated, thus the simple checks for *a
or *argv
.
1This applies only, if using std::vector<char*>
; if using std::vector<std::string>
, as actually proposed, even the strings themselves are copied!