I am building a command line tool and at the beginning whole line is a string. How could I convert:
string text = "-f input.gmn -output.jpg";
into
const char *argv[] = { "ProgramNameHere", "-f", "input.gmn", "-output.jpg" };
I am building a command line tool and at the beginning whole line is a string. How could I convert:
string text = "-f input.gmn -output.jpg";
into
const char *argv[] = { "ProgramNameHere", "-f", "input.gmn", "-output.jpg" };
If I had to use getopt
, and I knew I was starting with a white-space separated std::string
, I'd do this:
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <vector>
#include <cassert>
#include <cstring>
int main() {
https://stackoverflow.com/questions/236129/how-to-split-a-string-in-c
// My input
std::string sentence = "-f input.gmn -output.jpg";
// My input as a stream
std::istringstream iss(sentence);
// Create first entry
std::vector<std::string> tokens;
tokens.push_back("ProgramNameHere");
// Split my input and put the result in the rest of the vector
std::copy(std::istream_iterator<std::string>(iss),
std::istream_iterator<std::string>(),
std::back_inserter(tokens));
// Now we have vector<string>, but we need array of char*. Convert to char*
std::vector<char *> ptokens;
for(auto& s : tokens)
ptokens.push_back(&s[0]);
// Now we have vector<char*>, but we need array of char*. Grab array
char **argv = &ptokens[0];
int argc = ptokens.size();
// Use argc and argv as desired. Note that they will become invalid when
// *either* of the previous vectors goes out of scope.
assert(strcmp(argv[2], "input.gmn") == 0);
assert(argc == 4);
}
See also: Split a string in C++?
This code fragment will only compile if your compiler supports thew new features:
for(auto& s : tokens)
ptokens.push_back(&s[0]);
If you have an older C++ compiler, you might need to rewrite it using C++2003 features:
for(std::vector<string>::iterator it = tokens.begin(); it != tokens.end(); ++it)
ptokens.push_back(it->c_str());
or
for(std::vector<string>::size_type i = 0; i < tokens.size(); ++i)
ptokens.push_back(tokens[i].c_str());
I would recommend using boost::program_options to parse your program's arguments.
Otherwise if you are using MSVC, you might want to use the built-in __argc and __argv.
There is no portable way to get your program's image name, so you cannot get that information out of nowhere if you dropped it in the first place by discarding your original argv argument.
You could use the C strtok function to split your arguments ... actually scratch that, just use boost::algorithm::split with any_of(' ').