2

我需要创建多个函数来检查输入是否有效。以下是我的一些代码:

bool IsValidRange(signed char s)
{
    bool isValid = true;
    if (!((s>=SCHAR_MIN)&&(s<=SCHAR_MAX)))
    {
        isValid = false;
    }
    return isValid;
}

bool IsValidRange(int s)
{
    bool isValid = true;
    if (!((s>=INT_MIN)&&(s<=INT_MAX)))
    {
        isValid = false;
    }
    return isValid;
}

我为此使用了标头limits.h。我这样做对吗?请注意,我只是一个初学者。我希望你们都能理解。谢谢!

4

5 回答 5

6

the template above will not work for the mixture of signed and unsigned types, in addition to floats.

template<typename RangeType, typename ValueType >
bool IsInRange( ValueType value ) 
{
    if( ! numeric_limits<RangeType>::is_integer )
    {
        return  (value > 0 ? value  : -value) <= numeric_limits<RangeType>::max(); 
    }

    if ( numeric_limits<RangeType>::is_signed == 
         numeric_limits<ValueType>::is_signed )
    {
        return value >= numeric_limits<RangeType>::min() &&
               value <= numeric_limits<RangeType>::max();
    }
    else if( numeric_limits<RangeType>::is_signed )
    {
        return value <= numeric_limits<RangeType>::max();
    }
    else
    {
        return value >= 0 && value <=  numeric_limits<RangeType>::max();
    }
}
于 2015-02-17T22:38:29.750 回答
2

首先,您不需要所有带有布尔值的卷积。直接返回表达式:

return (s >= SCHAR_MIN) && (s <= SCHAR_MAX);

其次,你应该意识到你的两个函数总是 yield true:根据定义, asigned char总是在 range 内[SCHAR_MIN, SCHAR_MAX],而 anint总是在 range 内[INT_MIN, INT_MAX]

但是,如果您选择不同的界限,这确实是这样做的方法(考虑到我的第一句话)。

作为EdS。建议,您可以使用模板化解决方案来减少所需的函数/重载数量:

template<class T>
bool check_range(T value, T min, T max) {
    return (value >= min) && (value <= max);
}
于 2013-09-05T00:40:59.197 回答
2
#include <limits>

template<typename ValueType, typename RangeType >
bool IsInRange( ValueType value ) {
    return (value >= numeric_limits<RangeType>::min()) &&
           (value <= numeric_limits<RangeType>::max());
}

这将适用于除浮点值之外的整数数据类型。numeric_limits<T>::min()将返回浮点类型的最小标准化正值。引入 C++11numeric_limits<T>::lowest()来解决该问题。

于 2013-09-05T00:55:51.453 回答
0

这是基于 RadioKat 答案的实现,但它会抑制编译器警告,例如:

warning: pointless comparison of unsigned integer with zero
warning: integer conversion resulted in a change of sign

通过使用模板元编程:

#include <limits>

template< typename T_Range, typename T_Value, bool T_RangeSigned, bool T_ValueSigned >
struct InIntegerRange;

template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, false, false >
{
    bool operator()( T_Value const & x )
    {
        return x >= std::numeric_limits< T_Range >::min() &&
               x <= std::numeric_limits< T_Range >::max();
    }
};

template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, false, true >
{
    bool operator()( T_Value const & x )
    {
        return x >= 0 && x <= std::numeric_limits< T_Range >::max();
    }
};

template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, true, false >
{
    bool operator()( T_Value const & x )
    {
        return x <= std::numeric_limits< T_Range >::max(); /* x >= 0 is given */
    }
};

template< typename T_Range, typename T_Value >
struct InIntegerRange< T_Range, T_Value, true, true >
{
    bool operator()( T_Value const & x )
    {
        return x >= std::numeric_limits< T_Range >::min() &&
               x <= std::numeric_limits< T_Range >::max();
    }
};

template< typename T_Range, typename T_Value >
inline bool inRange( T_Value const & x )
{
    if( std::numeric_limits< T_Range >::is_integer )
    {
        return InIntegerRange< T_Range, T_Value,
                               std::numeric_limits< T_Range >::is_signed,
                               std::numeric_limits< T_Value >::is_signed >()( x );
    }
    else
    {
        return ( x > 0 ? x : -x ) <= std::numeric_limits< T_Range >::max() ||
               ( std::isnan(x) && std::numeric_limits< T_Range >::has_quiet_NaN ) ||
               ( std::isinf(x) && std::numeric_limits< T_Range >::has_infinity );
    }
}
于 2017-10-29T11:25:38.860 回答
0

答案很简单。如果将函数的参数定义为特定类型,则编译器会强制输入在声明类型的范围限制内。

因此,您的代码始终返回 true,并且检查过程实际上不起作用。

为了解决这类问题,您可以使用一种简单的技术。如何?让我解释一下:您可以选择一个限制大于您决定的实际值的参数。例如:如果参数是整数,则将其定义为 long 类型。

现在,您的检查过程将起作用。为什么?

因为你声明的数字可以接受比较可观的值,但是你最终会在检查过程中决定输入值应该是多少。

这个技巧在编译和内存使用方面可能会很昂贵,而且对于新手来说有点滑。但是对于非复杂函数和过程以及有限数量的参数或变量来说效果很好。

在您的计算机中检查以下代码并查看结果:

long i = 0L;
int left_limit = std::numeric_limits<int>::min();
int right_limit = std::numeric_limits<int>::max();

std::cout << "Enter an integer: ";
std::cin >> i;
if (i < left_limit || i > right_limit) {
        std::cout << "You have reached to out of limits." << std::endl;
        return false;
}
于 2021-02-01T19:46:36.903 回答