我需要创建多个函数来检查输入是否有效。 以下是我的一些代码:
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。我这样做是对的吗?请注意我只是一个初学者。我希望你们都明白。谢谢!
答案 0 :(得分:6)
除了浮点数之外,上面的模板不适用于有符号和无符号类型的混合。
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();
}
}
答案 1 :(得分: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 ++ 11引入了numeric_limits<T>::lowest()
来解决这个问题。
答案 2 :(得分:1)
首先,你不需要所有那些带有布尔值的卷积。只需直接返回表达式:
return (s >= SCHAR_MIN) && (s <= SCHAR_MAX);
其次,你应该意识到你的两个函数总是产生true
:根据定义,signed char
总是在[SCHAR_MIN, SCHAR_MAX]
范围内,int
始终在范围[INT_MIN, INT_MAX]
。
但如果你选择不同的界限,这确实是这样做的方式(考虑到我的第一句话)。
正如 EdS。建议的那样,您可以使用模板化解决方案来减少所需的函数/重载次数:
template<class T>
bool check_range(T value, T min, T max) {
return (value >= min) && (value <= max);
}
答案 3 :(得分: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 );
}
}
答案 4 :(得分: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;
}