【发布时间】:2021-06-23 01:07:31
【问题描述】:
所以我试图检查我输入到程序中的参数,其中之一是单词“yes”或“no”,输入时不带引号。
我正在尝试测试等效性( if (argv[n] == "yes") ),但是每次输入实际上是肯定的时,这似乎都会返回 false(当我输出它时,它证实了这一点)。我在这里错过了什么,我做错了什么? 如果我理解正确 argv[n] 返回一个以 null 结尾的 cstring,那么它应该允许我这样做。
【问题讨论】:
标签: c++
所以我试图检查我输入到程序中的参数,其中之一是单词“yes”或“no”,输入时不带引号。
我正在尝试测试等效性( if (argv[n] == "yes") ),但是每次输入实际上是肯定的时,这似乎都会返回 false(当我输出它时,它证实了这一点)。我在这里错过了什么,我做错了什么? 如果我理解正确 argv[n] 返回一个以 null 结尾的 cstring,那么它应该允许我这样做。
【问题讨论】:
标签: c++
您正在比较指针。使用 strcmp 或 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
}
}
}
【讨论】:
std::find而不是vector上的for循环的“简单模式”怎么样?
"yes" 本身实际上是指一个数组而不是一个指针,但它以通常的数组方式衰减为指向第一个元素的指针。
这是 std::string 的更好替代方案,当效率很重要时 - 在 C++17 中,您现在拥有非常有用的 std::string_view。这使您可以像使用 std::string 一样使用参数,而不会产生复制成本。
目前在 GCC 的 std::experimental 中可用:
#include <experimental/string_view>
...
if(std::experimental::string_view(argv[1]) == "yes") {
// do things
}
【讨论】:
if(strcmp(argv[0],"yes")==0) { // equal to "yes"
如果 2 个字符串相同,则 strcmp 为零。
【讨论】:
您还可以查看 boost::program_options,虽然这似乎有点离题和矫枉过正,但是一旦您习惯了它,它就可以轻松、方便且安全地使用。一些优点是为您的程序自动生成的 --help 以及诸如 使用 lexical_cast 可以安全地进行字符串求值。
【讨论】:
如果您不知道参数将出现在哪里,您可以考虑使用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`
// ....
}
【讨论】:
现代C++,有点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
}
注意:标准不保证你可以在main的签名中使用const,也不禁止。
正如这里所使用的,const 确保我们不会更改我们不打算更改的内容——这就是 C++ 语言中const 的目的。
另见...
【讨论】:
auto 要求?呸:(
argc+1 不必要的动态分配和 argc 完全不必要的字符串复制。至少让它成为一个字符串视图的向量......
int main( int argc, char * const argv[] ) 是不可移植的。 (您提供的链接不涵盖此用法)
argc == 0的情况下,这也会导致未定义的行为
auto 在 C++17 中是必需的。我今天学到了很多。 Is auto an optional keyword in ranged based for loops?