如何检查一个变量是否不等于 C++ 中的多个东西?

How do I check if a variable is not equal to multiple things in C++?

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

这是我的:

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

但是好像不行。我以为我可以用逗号来分隔它们,但也许我是在想象。

唯一的选择就是:

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

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

How do I check if a variable is not equal to multiple things

Is the only option to just do:

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

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

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

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

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

您可以将值存储在容器中并使用 std::find_if, std::none_of or std::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";
    }
 }

如果您正在寻找更通用和人类可读的构造,您可以创建如下内容:

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

简单而有效的方法。

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)。输入数字高时很好。如果您的索引等于集合的结尾,它不存在于列表中,您将得到集合的结尾作为索引,这对您来说是无效输入。否则你会将其视为有效输入

如果你正在寻找 "if a string is not equal to multiple strings in C" 你可以使用下面的(不是每个人都会认为它优雅,但如果你喜欢好的老式 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;
}