Checking argv[] against a string? (C++)
So I'm attempting to check the arguments that I'm inputting into my program, and one of them is either the word "yes" 开发者_Go百科or "no", entered without the quotes.
I'm trying to test equivalency ( if (argv[n] == "yes") ) but that seems to be returning false every time when the input is, in fact, yes(When I output it it confirms this). What am I missing here that I'm doing improperly? If I understand properly argv[n] returns a cstring that is null-terminated, so it should allow me to do this.
You're comparing pointers. Use strcmp, or std::string.
int main(int argc, char * argv[]) {
if (argv[1] == "yes"); // Wrong, compares two pointers
if (strcmp(argv[1], "yes") == 0); // This compares what the pointers point to
if (std::string(argv[1]) == "yes"); // Works fine
if (argv[1] == std::string("yes")); // Works fine
// Easy-mode
std::vector<std::string> args(argv, argv+argc);
for (size_t i = 1; i < args.size(); ++i) {
if (args[i] == "yes") {
// do something
}
}
}
Here's a better alternative to std::string, and when efficiency is important - in C++17 you now have the very useful std::string_view. This lets you work with the arguments similarly to a std::string, without incurring the cost of copying.
Currently available in std::experimental in GCC:
#include <experimental/string_view>
...
if(std::experimental::string_view(argv[1]) == "yes") {
// do things
}
if(strcmp(argv[0],"yes")==0) { // equal to "yes"
strcmp is zero if the 2 strings are the same.
You could also take a look into boost::program_options, though this seems a little off topic and overkill, but once you get used to it it's easy, convenient and safe to use. Some advantages are auto-generated --help for your program, plus things like string evaluation can be done safe using lexical_cast.
If you don't know exactly where the argument will appear, you might consider using find_if
(C++17):
#include <algorithm>
#include <string>
int main(int argc, char * argv[])
{
auto const begin = argv;
auto const end = argv + argc;
auto is_yes = [](std::string const & s) { return s == "yes"; };
auto const it = std::find_if(begin, end, is_yes);
// do stuff with `it`
// ....
}
Modern C++, with a bit of const
correctness...
/*BINFMTCXX: -Wall -Werror -std=c++17
*/
#include <iostream>
#include <string>
#include <vector>
using std::string; using std::vector; using std::cerr;
int main( int argc, char * const argv[] )
{
assert( argc >= 1 ); // exploratory -- could fail in principle, but not really
const vector<string> args(argv+1,argv+argc); // convert C-style to modern C++
for ( auto a : args ) cerr<<(a=="yes")<<"\n"; // operator '==' works as expected
}
Note: The standard doesn't guarantee that you can use const
in the signature of main
, nor does it forbid it.
As used here, const
ensures that we won't change things we don't intend to change -- which is the purpose of const
in the C++ language.
See also...
- Passing argv as const
- What is the proper declaration of main?
- int getopt(int argc, char * const argv[], const char *optstring) -- notice signature
- What does int argc, char *argv[] mean? -- min value of
argc
精彩评论