2

Usually I see:

int main(int argc, char** argv)

But can I use:

int main(int argc, std::string* argv)

instead?

If it's not possible how can I convert char* to std::string?

PS: I am using C++11.

anastaciu
  • 20,013
  • 7
  • 23
  • 43
raghad
  • 145
  • 8

4 Answers4

5

main argument must be char** argv or char* argv[].

[basic.start.main]

2. An implementation shall not predefine the main function. This function shall not be overloaded. Its type shall have C++ language linkage and it shall have a declared return type of type int, but otherwise its type is implementation-defined. An implementation shall allow both

(2.1). a function of () returning int and

(2.2). a function of (int, pointer to pointer to char) returning int


What you can do is to convert the arguments in the code by using one of the following:

  • Simply assigning it:
    if(argc > 1)
    { 
        std::string str = argv[1]; 
    }
  • Constructing the string using the argument as the constructor parameter:
    std::string str(argv[1]);
  • With initializer list:
    std::string str{argv[1]};

If you'd like to keep a collection of the arguments I would suggest keeping them in a variable size container std::vector using one of the following:

  • Constructing vector in place using std::vector constructor, here using pointers to the beginning and to one past the end the array of strings argv as constructor arguments:
    std::vector<std::string> strs(&argv[1], &argv[argc]); //*
  • Using initializer list:
    std::vector<std::string> strs{&argv[1], &argv[argc]}; //*
  • Adding the arguments in a loop:
    std::vector<std::string> strs;

    for(int i = 1; i < argc; i++) //*
        strs.push_back(argv[i]);   
    }

*Not including argv[0] program name.

anastaciu
  • 20,013
  • 7
  • 23
  • 43
2

No, but there has been some discussion of this in standards committee

In Paper P0781, Erich Keane suggests having the standard allow for the following:

int main(const some_container<const some_string_type> args){
  for (auto Arg : args) {
    // some usage of this character array...
  }
}

There's the question of which container and which string type should be used. Mr. Keane suggests an initializer_list of string_view's - not std::string's, because the latter ones require a bunch of resources, while string_view's are very lightweight.

einpoklum
  • 86,754
  • 39
  • 223
  • 453
2

No, but you can create a std::vector<std::string> by using the vector constructor that takes iterators:

template< class InputIt >
vector( InputIt first, InputIt last, const Allocator& alloc = Allocator());

So to put the arguments (excluding the program name) in a vector:

std::vector<std::string> args(argv + 1, argv + argc);

To separate your ordinary main from your enhanced main you could do it like this:

#include <iostream>
#include <string>
#include <vector>

int cppmain(std::string program, std::vector<std::string> args) {
    std::cout << program << " got " << args.size() << " argument(s):\n";

    for(auto& arg : args) { // each argument as a string
        std::cout << " " << arg << '\n';
    }
    return 0;
}

int main(int argc, char* argv[]) {
    //
    //         string from char*
    //                |
    //                V
    return cppmain(argv[0], {argv + 1, argv + argc});
    //                      ^                     ^
    //                      |                     |
    //                     vector<string> from char*[]
}
Ted Lyngmo
  • 37,764
  • 5
  • 23
  • 50
1

No, you can't. But you can use something like the following to store them as std::strings

#include <iostream>
#include <string>
#include <vector>

int main(int argc,char** argv){
    std::vector<std::string> strings(argc-1);
    for(size_t i{}; i < strings.size();++i){
        strings[i] = std::string{argv[i+1]};
    }
    for(const auto& el :strings)
        std::cout << el << " ";


    return 0;
}
Jesper Juhl
  • 1
  • 3
  • 38
  • 63
asmmo
  • 6,409
  • 1
  • 7
  • 22