【问题标题】:Checking argv[] against a string? (C++)根据字符串检查 argv[]? (C++)
【发布时间】:2021-06-23 01:07:31
【问题描述】:

所以我试图检查我输入到程序中的参数,其中之一是单词“yes”或“no”,输入时不带引号。

我正在尝试测试等效性( if (argv[n] == "yes") ),但是每次输入实际上是肯定的时,这似乎都会返回 false(当我输出它时,它证实了这一点)。我在这里错过了什么,我做错了什么? 如果我理解正确 argv[n] 返回一个以 null 结尾的 cstring,那么它应该允许我这样做。

【问题讨论】:

标签: c++


【解决方案1】:

您正在比较指针。使用 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循环的“简单模式”怎么样?
  • std::find 如果他问“是我的论点之一是”就很好。他在问“这个论点是是还是不是”。这是对问题的解释,重读它我发现你的解释也可能是正确的。
  • @Ben: "yes" 本身实际上是指一个数组而不是一个指针,但它以通常的数组方式衰减为指向第一个元素的指针。
【解决方案2】:

这是 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
}

【讨论】:

    【解决方案3】:
    if(strcmp(argv[0],"yes")==0) { // equal to "yes"
    

    如果 2 个字符串相同,则 strcmp 为零。

    【讨论】:

      【解决方案4】:

      您还可以查看 boost::program_options,虽然这似乎有点离题和矫枉过正,但是一旦您习惯了它,它就可以轻松、方便且安全地使用。一些优点是为您的程序自动生成的 --help 以及诸如 使用 lexical_cast 可以安全地进行字符串求值。

      【讨论】:

        【解决方案5】:

        如果您不知道参数将出现在哪里,您可以考虑使用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`
            // ....
        }
        

        【讨论】:

          【解决方案6】:

          现代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 的目的。

          另见...

          【讨论】:

          • 哦,天哪,他们最后是否放弃了 range-for 中的 auto 要求?呸:(
          • “将 C 风格转换为现代 C++” 它的作用不止于此 - 它会邀请 argc+1 不必要的动态分配和 argc 完全不必要的字符串复制。至少让它成为一个字符串视图的向量......
          • int main( int argc, char * const argv[] ) 是不可移植的。 (您提供的链接不涵盖此用法)
          • argc == 0的情况下,这也会导致未定义的行为
          • @LightnessRacesinOrbit:你说得对——auto 在 C++17 中是必需的。我今天学到了很多。 Is auto an optional keyword in ranged based for loops?
          猜你喜欢
          • 2010-12-16
          • 2016-02-22
          • 2021-06-17
          • 1970-01-01
          • 2016-06-05
          • 1970-01-01
          • 2023-03-31
          • 2016-11-05
          • 2014-11-09
          相关资源
          最近更新 更多