I have changed my code, now while the compilation these errors occur:
`check.cpp: In function ‘int main()’:`
check.cpp:14:55: error: invalid conversion from ‘const char**’ to ‘char* const*’ [-fpermissive]
/usr/include/getopt.h:152:12: error: initializing argument 2 of ‘int getopt(int, char* const*, const char*)’ [-fpermissive]
int main() {
string text="-f input.gmn -output.jpg";
int argc=text.length();
cout<<"argc: "<<argc<<endl;
char const * argv = text.c_str();
cout<<"argv: "<<argv<<endl;
int c = getopt (argc, &argv, "f:s:o:pw:h:z:t:d:a:b:?");
return 0;
}
You can use text.c_str()
to convert a std::string
into a const char*
. See here.
To elaborate on my answer, there are many ways to create the array you need, but this is already described here, here, here and here. A simple solution to your problem that does not involve new
/malloc
or intensive uses of the STL and istringstream
/back_inserter
/copy
what not and performs really fast could look like this:
/* variables. */
std::vector< char* > argv;
int i, argc, state;
char c;
/* convert string to char string with automatic garbage collection. */
std::vector< char > tokens(text.begin(), text.end());
tokens.push_back(0);
/* tokenize string with space. */
for (state=0, argc=0, i=0; (c=tokens[i]); i++) {
if (state) {
if (c == ' ') {
tokens[i]=0;
state=0;
}
} else {
if (c != ' ') {
argv.push_back(&tokens[i]);
argc++;
state=1;
}
}
}
/* print argv. */
std::cout << "argc: " << argc << std::endl;
for (i=0; i < argc; i++) {
std::cout << "argv[" << i << "]: " << argv[i] << std::endl;
}
/* call getopt. */
c = getopt(argc, &argv[0], "f:s:o:pw:h:z:t:d:a:b:?");
This is just an example, but one advantage of this kind of code is that you can use other characters as delimiter, not just space, and that you need not care about releasing the allocated memory since std::vector
does this for you on function exit.
In short, you have an array argv which contains 100 pointers to strings, of which only the first is set. argv[1] hasn't been set to anything, so is pointing somewhere random. And in this case, illegal.
Moreoever, what getoption expects is going to be more like this:
argv[0] = "progname";
argv[1] = "-f";
argv[2] = "input.gmn"
argv[3] = "-output.jpg"
argv[4] = 0
Note the =0 at the end to stop getoption chargins through random bits of memory
First bug with your code is the comparison:
for (int i=0; i<=stringLength; i++) {
arv[i]=text[i];
}
Use i< stringLength
instead of i<=stringLength
.
The second bug is that arv
is not null-terminated.
After fixing both bugs, your code should look like this:
for (int i=0; i < stringLength; i++) {
arv[i]=text[i];
}
arv[stringLength] = '\0';
By the way, the correct function signature of getopt
is this:
int getopt(int argc, char * const argv[], const char *optstring);
which takes second and third argument as const
. That means, you can do this:
char const * s = text.c_str();
int c = getopt (argc, &s, "f:s:o:pw:h:z:t:d:a:b:?");
No need of any conversion, using manual loop.