【问题标题】:How do I check if a variable is not equal to multiple things in C++?如何检查一个变量是否不等于 C++ 中的多个事物?
【发布时间】:2018-08-01 10:57:26
【问题描述】:

我正在编写一段代码,用于检查用户输入的内容是否实际上是有效输入之一(在本例中为 1-9),如果不是,则会给出错误消息。

这就是我所拥有的:

if (input != '1', '2' , '3' , '4' , '5' , '6' , '7' , '8' , '9' , '0' )
    {
      cout << "Error";
    }

但它似乎不起作用。我以为我可以用逗号来分隔它们,但也许我在想象。

是唯一的选择:

input != '1' && input != '2' && input != '3' etc etc

我知道这种方法可行,但似乎有点啰嗦。有没有更简单的方法?

【问题讨论】:

  • 也许这会启发你:stackoverflow.com/a/51408285/1413395
  • 使用&gt;/&gt;=&lt;/&lt;=。在 C 支持的任何编码中,数字都保证按 '0''9' 的顺序排列。(例如 if (input &lt; '0' || input &gt; '9')
  • 这个问题很可能会被否决,并且对于家庭作业副本没有答案。但是你总是可以使用 switch 以防 "if" 有太多选项,并将默认情况作为错误,如 switch(input){ case 1: ... default: Error;休息; }
  • 在这种特殊情况下,另一个选项是isdigit()
  • @DevSolar 这没关系,字符文字根据执行字符集进行翻译。如果 this 与执行机器上实际使用的字符集不匹配,你的问题会更严重——当然,isdigit() 也不起作用。

标签: c++ variables operators


【解决方案1】:

您可以将值存储在容器中并使用std::find_ifstd::none_ofstd::any_of 函数:

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<char> v = { '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
    char input = '1';
    if (std::none_of(v.cbegin(), v.cend(), [&input](char p){ return p == input; })) {
        std::cout << "None of the elements are equal to input.\n";
    } 
    else {
        std::cout << "Some of the elements are equal to input.\n";
    }
 }

【讨论】:

    【解决方案2】:

    如何检查一个变量是否不等于多个事物

    是唯一的选择:

    input != '1' && input != '2' && input != '3' etc etc
    

    在一般情况下,对于任意一组值:不,这不是唯一的选择,但它是最简单的。而最简单往往是最好的,或者至少足够好。

    如果您不喜欢 input != 的冗余重复,可以使用可变参数模板来生成表达式。我在另一个问题中写了一个例子:https://stackoverflow.com/a/51497146/2079303

    在特定情况下,可能会有更好的选择。存在std::isdigit,例如对于您的示例代码中的特定情况。

    为了检查一个变量是否(不)等于多个直到运行时才知道的东西,典型的解决方案是使用一个集合数据结构,例如std::unordered_set

    【讨论】:

    • 在这种情况下,我只是以数字为例,输入将是单词。不过感谢您的帮助。
    • 这不是 OP 要求的,这不是更简单的方法。
    • @ProXicT This isn't what the OP asked for 你认为 OP 要求什么? this isn't a simpler way to do it.我回答说OP的建议是最简单的解决方案。显然,OP 的建议并不比 OP 的建议简单。同样简单。
    【解决方案3】:

    如果您正在寻找更通用且更易于阅读的构造,您可以创建如下内容:

    template <typename T, int TSize>
    struct AnyOfThis {    
        template <typename TFirst, typename... TOthers>
        explicit AnyOfThis(TFirst&& first, TOthers&&... others)
            : values({ std::forward<TFirst>(first), std::forward<TOthers>(others)... }) {}
    
        std::array<T, TSize> values;
    };
    
    template <typename TFirst, typename... TOthers>
    auto anyOf(TFirst&& first, TOthers&&... others) {
        constexpr std::size_t size = 1 + sizeof...(others);
        return AnyOfThis<typename std::decay<TFirst>::type, size>(std::forward<TFirst>(first),
                                                                  std::forward<TOthers>(others)...);
    }
    
    template <typename T, int TSize>
    bool operator==(const T value, const AnyOfThis<typename std::decay<T>::type, TSize>& anyOfThis) {
        return std::find(anyOfThis.values.begin(), anyOfThis.values.end(), value) != anyOfThis.values.end();
    }
    

    基本上,它从可变参数函数创建一个静态数组。然后还有另一个函数用作比较器,它获取您要比较的值并在数组中查找该值。

    用例也读起来相当不错:

    if (1 == anyOf(1, 2, 3)) {
        // do stuff
    }
    

    LIVE DEMO AT COLIRU

    【讨论】:

      【解决方案4】:

      简单而有效的方法。

      std::unordered_set<char> allowedValues = {'1','2','3','4','5','6','7','8','9','0'};
      std::unordered_set<char>::const_iterator index = allowedValues.find(input);
      if(index == allowedValues.end())
        std::cout << "Error";
      else
        std::cout << "Valid";
      

      通过使用无序集,您期望 O(1) 的查找复杂度。输入数字高时很好。如果您的索引等于集合的结尾,它在列表中不存在,您将得到集合的结尾作为索引,这对您来说是无效的输入。否则你会将其视为有效输入

      【讨论】:

        【解决方案5】:

        如果您正在寻找“如果 string 不等于 C 中的多个 strings”,您可以使用以下内容(不是每个人会认为它很优雅,但如果您喜欢旧的 c-str,那么您可能会觉得它不错。当然,它简单快捷):

        int GetIdxOfStringInOptionList (const char *Xi_pStr)
        {
            char l_P2[205];
            sprintf(l_P2, "<@%s^>", Xi_pStr);  // TODO: if (strlen>=200) return -1. Note that 200 is above length of options string below
            _strlwr(l_P2);                     // iff you want comparison to be case insensitive
            const char *l_pCO = strstr("01<@gps^>02<@gps2^>03<@log^>04<@img^>05<@nogps^>06<@nogps2^>07<@gps3^>08<@pillars0^>09<@pillars1^>10<@pillars2^>11<@pillars3^>", l_P2);
            return l_pCO? atoi(l_pCO-2) : -1;
        }
        

        【讨论】:

          猜你喜欢
          • 2011-11-20
          • 2019-11-17
          • 2018-03-27
          • 2023-01-19
          • 2021-03-28
          • 2020-01-16
          • 1970-01-01
          • 2014-12-04
          相关资源
          最近更新 更多