Reputation: 149
I have to test the function
std::vector<std::string> convert_arguments(int argc, char **argv) {
[some code]
return command_arguments;
};
that takes a pointer to an array of command arguments and returns a Vector containing those arguments. The function works well. But I'm having trouble constructing such a pointer myself. The array is an array of strings, i.e. an array of array of chars. As far as I know, the pointer is supposed to point to the first pointer of the pointers pointing to the first letters of the strings (that sounds quite strange). What I need is an exemplary pointer **argv that I can pass to the function to see if it works. I know that there are a lot of similar questions on the internet, but I couldn't really find an answer that works for me. I would be very thankful if you could help me out, because I've been looking for an answer for several hours.
Upvotes: 1
Views: 540
Reputation: 11219
You can achieve this with a pointer of char arrays in the C fashion:
#include <vector>
#include <string>
#include <iostream>
using namespace std;
// borrowed from prehistoricpenguin
std::vector<std::string> convert_arguments(int argc, const char **argv) {
return std::vector<std::string>(argv + 1, argv + argc);
}
bool test1(void) {
int argc = 5;
const char *argv[] = {"program_name", "some string", "another", "command", "ok", NULL };
std::vector<std::string> myexpectedvector = {"some string", "another","command", "ok" };
std::vector<std::string> s = convert_arguments(argc, argv);
return (s == myexpectedvector);
}
int main () {
std::cout << test1() << std::endl;
}
Upvotes: 0
Reputation: 6326
A one-line version:
std::vector<std::string> convert_arguments(int argc, const char **argv) {
return std::vector<std::string>(argv + 1, argv + argc);
}
Or even simpler with c++11 above
std::vector<std::string> convert_arguments(int argc, const char **argv) {
return {argv + 1, argv + argc};
}
Explanation:
We call the constructor for std::vector
with two iterator ranges(pointer can be treat as an iterator), since argv is a pointer arry, the left range is argv+1
, the right range is argv + argc
.
For the std::string
constructor, the const char*
is passed.
Upvotes: 0
Reputation: 148880
The command line arguments use both conventions to pass the number of arguments:
argc
argv
array contains a null pointer as its last (useful) elementAs you can construct a string for a const char *
, code can be as simple as:
std::vector<std::string> convert_arguments(int argc, char **argv) {
std::vector<std::string> command_arguments;
for (int i=0; i<argc; i++) {
command_arguments.push_back(std::string(argv[i]));
}
return command_arguments;
}
or (second convention):
std::vector<std::string> convert_arguments(int argc, char **argv) {
std::vector<std::string> command_arguments;
for (const char **ix=argv; ix!=nullptr; ix++) {
command_arguments.push_back(std::string(*ix++));
}
return command_arguments;
}
If you want to build such an array for tests, you can easily do it from literal strings:
const char *const_argv[] = { "foo", "fee", "bar", "baz", nullptr}; // add the last null
int my_argc = sizeof(my_argv)/sizeof(*my_argv) - 1; // but do no count it
char ** my_argv = const_cast<char **>(const_argv); // cast it
Beware: This code correctly declared const_argv
to be an array of pointers to const characters, because a string literal is const, and uses const_cast
to be able to pass it to above function. It is harmless because the function never try to change its parameters but the rule is that const_cast
should be avoided if possible.
If you really need an array of non const strings, you must build the strings first and then the array:
char a1[] = "foo";
char a2[] = "fee";
char a3[] = "bar";
char a4[] = "baz";
char *argv[] = {a1, a2, a3, a4, nullptr};
Upvotes: 2
Reputation: 1637
char** argv
is really just a 2 dimensional array. You can create such an array via
char** argv = new char*[argc];
. Then you can just loop over the argv array with for(int i=0;i < argc; ++i)
and assaign whatever string you want to each entry.
Upvotes: 2
Reputation: 1
Here the argc stores number of arguments passed and argv stored all the arguments. You can do something like,
std::vector<std::string> vec;
for (int counter=1;counter<argc;counter++) //0th argument is the program name
{
vec.push_back(argv[counter]); //push each string into vector
}
return vec;
Upvotes: 0