Reputation: 3631
I would like to modify or erase a 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 contained in the list.
What's the best way to do this?
Upvotes: 4
Views: 8192
Reputation: 20336
Since you are using C++, you could convert all your C-like strings in std::string. Since this operation is done once at the beginning of the program, there is no efficiency 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's 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 any reason you still need itemFound you can set it in the if block.
(Note: you do not need braces when you have a block with a single statement, although this is a battled topic :) https://softwareengineering.stackexchange.com/questions/16528/single-statement-if-block-braces-or-no)
Edit (taking care of existence of 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's 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]) );
Upvotes: 1
Reputation: 7343
Did you try debugging? If you do, you will see that it never attempts to erase anything.
You can't compare strings (char*
) with simple equality, because in reality you're comparing pointers, which will (almost) never be equal. Instead, you should use string comparison functions, like this:
if (!strcmp(argv[i], "--item")) {
Also, since you're overwriting the argument, you don't need to use a lot of 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 could shift the rest of the arguments so you don't end up with gaps which could confuse the rest of your code.
Upvotes: 3