9

Hi very newbie question but I just can't figure it out:

I have a function named bar

class foo
{
    public:
        bool bar(int argc, char** argv);
}

argv is supposed to contain

"--dir" and "/some_path/"

How do I create argv and argc so that I can pass them into bar() ? I've tried many ways but I just can't get pointer and type conversion right.

So instead of getting argv from command line, I want to create it in the code.

Thank you for any input!

KKsan
  • 147
  • 1
  • 1
  • 8
  • you create?? no! you can pass arguments to your program through argv. argc is the number of parameters passed in. argv can hold anything values, paths... – Raindrop7 Oct 05 '16 at 20:55
  • @Raindrop7, sometimes you have to create argc and argv inside of a programm. For example if you want to use boost unit test, you will eventually call main. And on android (if you want to run tests on device) you have to call it yourself and you have to form arguments for it. – Alexey Guseynov Oct 05 '16 at 21:02

2 Answers2

24

My favourite way is like this:

std::vector<std::string> arguments = {"--dir", "/some_path"};

std::vector<char*> argv;
for (const auto& arg : arguments)
    argv.push_back((char*)arg.data());
argv.push_back(nullptr);

f.bar(argv.size() - 1, argv.data());

Note, that if arguments are static and do not change, then this is a little bit overkill. But this approach has advantage of being RAII compliant. It manages memory for you and deletes objects at right moment. So if argument list is dynamic, then it is the cleanest way.

Beside that, this code technically is UB if f.bar modifies data in argv array. Usually this is not the case.

Alexey Guseynov
  • 5,116
  • 1
  • 19
  • 29
6

Assuming you want argc and argv in the same format that are passed to main, you can call it like this:

foo f;
char *args[] = {
    (char*)"--dir",
    (char*)"/some_path/",
    NULL
};
f.bar(2, args);

(note: this assumes bar won't modify the argument strings - in which case you should change the argument type to const char ** instead of char **)

user253751
  • 57,427
  • 7
  • 48
  • 90
  • 2
    Conversion from `const char *` to `char *` is illegal in c++ – Slava Oct 05 '16 at 20:56
  • segfault! no allocation for argv – Raindrop7 Oct 05 '16 at 20:58
  • @Slava No, it's not. The conversion, if made explicit by a cast, is valid in all versions of C++. Until C++11, the conversion could also be performed implicitly, but only for string literals (which this answer has). Only attempts to modify the pointed-to string are invalid. –  Oct 05 '16 at 21:02
  • 1
    @Raindrop7 argv is an array of pointers. Array is on stack, no allocation needed. Pointers are pointers to constants located in data section. No allocation needed either. – Alexey Guseynov Oct 05 '16 at 21:04
  • @AlexeyGuseynov yes you can pass arguments to another functions even main for example in winmain returns a call to main passing to it argc and argv. – Raindrop7 Oct 05 '16 at 21:23
  • "Attempting to modify a string literal results in undefined behavior: they may be stored in read-only storage (such as .rodata) or combined with other string literals" https://en.cppreference.com/w/cpp/language/string_literal – etam1024 Dec 03 '19 at 13:27