Change argv command line argument

I would like to change or remove the command line argument in argv .

 //Somewhere near the top of main() bool itemFound(false); for(int i=1; i<argc; ++i) { if(argv[i] == "--item") { itemFound = true; //And remove this item from the list argv[i] = " "; //Try to remove be just inserting spaces over the arg } } //Now, use argc/argv as normal, knowing that --item is not in there 

However, --item is still listed.

What is the best way to do this?

+4
source share
2 answers

Have you tried to debug? If you do this, you will see that he never tries to erase anything. You cannot compare strings ( char* ) with simple equality, because in fact you are comparing pointers that (almost) will never be equal. Instead, you should use string comparison functions, for example:

 if (!strcmp(argv[i], "--item")) { 

In addition, since you are rewriting the argument, you do not need to use many spaces, you can simply set it to an empty string ( argv[i] = "" ) or modify the existing string to make it empty ( argv[i][0] = 0 ). Alternatively, you can move the rest of the arguments so that in the end there are no spaces that could confuse the rest of your code.

+3
source

Since you are using C ++, you can convert all your C-like strings to std :: string. Since this operation is performed once at the beginning of the program, there is no performance problem.

 //Somewhere near the top of main() bool itemFound(false); for(int i=1; i<argc; ++i) { if(std::string(argv[i]) == std::string("--item") ) { itemFound = true; //And remove this item from the list argv[i][0] = 0; //Transform it in an empty string, putting null as first character } } //Now, use argc/argv as normal, knowing that --item is not in there 

Otherwise (avoiding hacking with argv):

 std::vector<std::string> validArgs; validArgs.reserve(argc); //Avoids reallocation; it one or two (if --item is given) too much, but safe and not pedentatic while handling rare cases where argc can be zero for(int i=1; i<argc; ++i) { const std::string myArg(argv[i]); if(myArg != std::string("--item") ) validArgs.push_back(myArg); } 

If for some reason you still need itemFound, you can set it in the if block.

(Note: you do not need brackets if you have a single statement block, although this is a moot point :) https://softwareengineering.stackexchange.com/questions/16528/single-statement-if-block-braces-or-no )

Edit (respecting comparison operators between std :: string and char *)

 bool itemFound(false); for(int i=1; i<argc; ++i) { if(std::string("--item") == argv[i] ) { itemFound = true; //And remove this item from the list argv[i][0] = 0; //Transform it in an empty string, putting null as first character } } 

or

 std::vector<std::string> validArgs; validArgs.reserve(argc); //Avoids reallocation; it one or two (if --item is given) too much, but safe and not pedentatic while handling rare cases where argc can be zero for(int i=1; i<argc; ++i) if(std::string("--item") != argv[i] ) validArgs.push_back(std::string(argv[i]) ); 
+1
source

Source: https://habr.com/ru/post/1486567/


All Articles