限制cin.操作符到特定范围
restrict cin. operator to a specific range
如果我想限制cin操作符的范围该怎么办?就像下面的代码一样,我从用户那里获取输入,现在输入必须小于100,即如果用户输入标记> 100,它应该报告一个错误消息。
using namespace std;
void GetInput(const std::string &prompt, int &i, int max)
{
bool valid = false;
do
{
cout << prompt;
if (cin >> i && i < max)
{
valid = true;
}
else
{
cout << "Error: Input must be less than " << max << "." << endl;
}
} while (!valid);
}
class Marks
{
private:
int elec, prog, math, perc = NULL;
public:
void input()
{
cout << "enter the marks obtained in Mathematics = ";
cin >> math;
cout << "enter the marks obtained in Programming = ";
cin >> prog;
cout << "enter the marks obtained in Electronics = ";
cin >>elec;
}
void avg()
{
double avg = NULL;
avg = (math + prog + elec) / 3;
cout << "Average = " << avg << endl;
}
void Perc()
{
perc = ((math + elec + prog)*100) / 300;
cout << "The Percentage = " << perc <<" %"<< endl;
}
void grade()
{
if (perc >= 79)
{
cout << "A" << endl;
}
else if ((perc > 66) && (perc < 80))
cout << "B" << endl;
else if (perc < 66)
cout << "C" << endl;
}
};
int main(void)
{
Marks m;
int maths, prog, elec;
GetInput("enter the marks obtained in Mathematics = ", maths, 100);
GetInput("enter the marks obtained in Programming = ", prog, 100);
GetInput("enter the marks obtained in Electronics = ", elec, 100);
m.Perc();
m.avg();
m.grade();
system("PAUSE");
return 0;
}
你可以尝试这样做:
int maths;
bool valid = false;
do
{
cout << "Enter the marks obtained in Mathematics = ";
if (cin >> maths && maths < 100)
{
valid = true;
}
else
{
cout << "Error: Input must be less than 100." << endl;
}
} while (!valid);
这将确保输入是一个有效的整数值且小于100,只有在输入了有效的输入后才终止循环。
一般操作:
void GetInput(const std::string &prompt, int &i, int max)
{
bool valid = false;
do
{
cout << prompt;
if (cin >> i && i < max)
{
valid = true;
}
else
{
cout << "Error: Input must be less than " << max << "." << endl;
}
} while (!valid);
}
在你的代码中调用它:
int maths, prog, elec;
GetInput("enter the marks obtained in Mathematics = ", maths, 100);
GetInput("enter the marks obtained in Programming = ", prog, 100);
GetInput("enter the marks obtained in Electronics = ", elec, 100);
在这种情况下,稍微重载操作符可以隐藏可重用helper类中的复杂性:
template<typename TMin, typename TMax>
struct unbound_limit_range
{
const TMin lower_limit;
const TMax upper_limit;
};
template<typename TMin, typename TMax>
class bound_limit_range
{
std::istream& the_stream;
const unbound_limit_range<TMin, TMax> the_limits;
public:
bound_limit_range(istream& p_stream, const unbound_limit_range<TMin, TMax>& p_limits)
: the_stream(p_stream), the_limits(p_limits)
{}
template<typename TVar>
istream& operator>>(T& dest)
{
while (true) {
if (!(the_stream >> dest)) return the_stream;
if (dest < the_limits.lower_limit) {
std::cout << "Value too lown";
}
else if (dest > the_limits.upper_limit) {
std::cout << "Value too highn";
}
else {
return the_stream;
}
std::cout << "Try again: " << std::flush;
}
}
};
template<typename TMin, typename TMax>
bound_limit_range<TMin, TMax> operator>>(std::istream& stream, const limit_range<TMin, TMax>& limits) { return { stream, limits }; }
template<typename TMin, typename TMax>
unbound_limit_range<TMin, TMax> limit_range(TMin lower, TMax upper) { return { lower, upper }; }
很乱,但是你可以简单地写:
cout << "enter the marks obtained in Mathematics = ";
cin >> limit_range(0, 100) >> maths;
cout << "enter the marks obtained in Programming = ";
cin >> limit_range(0, 100) >> prog;
cout << "enter the marks obtained in Electronics = ";
cin >> limit_range(0, 100) >> elec;
if (cin) { /* all succeeded */ }
您可以创建一个操纵符来为您做这些:
#include <iostream>
template<int, int>
struct input_range_impl
{
input_range_impl(int& val) : val_(val)
{
}
template<int I, int U>
friend std::istream& operator>>(std::istream&, const input_range_impl<I, U>&);
private:
int& val_;
};
template<int I, int U>
std::istream& operator>>(std::istream& is, const input_range_impl<I, U>& manip)
{
if (!(is >> manip.val_) || !(I <= manip.val_ && manip.val_ >= U))
is.setstate(std::ios_base::failbit);
return is;
}
template<int I, int U>
input_range_impl<I, U> input_range(int& val)
{
return { val };
}
void input()
{
std::cout << "enter the marks obtained in Mathematics = ";
std::cin >> input_range<0, 100>(maths);
std::cout << "enter the marks obtained in Programming = ";
std::cin >> input_range<0, 100>(prog);
std::cout << "enter the marks obtained in Electronics = ";
std::cin >> input_range<0, 100>(elec);
}
除了我的另一个答案之外,这里还有另一种设置范围的方法,但将语义合并到安装在流的区域设置中的std::num_get<facet>
中。这有点复杂,但它覆盖了流提取整数的默认行为,并使用自定义范围检查代码:
#include <iostream>
#include <utility>
int input_range() { static int idx = std::ios_base::xalloc(); return idx; }
void erase_range(std::ios_base::event evt, std::ios_base& str, int index)
{
if (evt == std::ios_base::erase_event)
{
delete static_cast<std::pair<int, int>*>(str.pword(index));
}
}
class num_get : public std::num_get<char>
{
public:
iter_type do_get( iter_type in, iter_type end, std::ios_base& str,
std::ios_base::iostate& err, long& v ) const
{
long temp;
in = std::num_get<char>::do_get(in, end, str, err, temp);
if (in != end)
err |= std::ios_base::failbit;
void*& p = str.pword(input_range());
if (p)
{
auto values = *static_cast<std::pair<int, int>*>(p);
if (!(values.first <= temp && temp <= values.second))
{
err |= std::ios_base::failbit;
} else
v = temp;
}
return in;
}
};
template<int I, int J>
std::istream& set_range(std::istream& is)
{
void*& p = is.pword(input_range());
erase_range(std::ios_base::erase_event, is, input_range());
if (is)
{
p = new std::pair<int, int>(I, J);
if (!dynamic_cast<const num_get*>(
&std::use_facet<std::num_get<char>>(is.getloc())))
{
is.imbue(std::locale(is.getloc(), new num_get));
is.register_callback(&erase_range, input_range());
}
}
return is;
}
你可以这样使用:
void input()
{
std::cin >> set_range<0, 100>;
std::cout << "enter the marks obtained in Mathematics = ";
if (!(std::cin >> maths))
std::cout << "Error!";
std::cout << "enter the marks obtained in Programming = ";
// so on...
std::cout << "enter the marks obtained in Electronics = ";
// and so forth...
}
相关文章:
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- C++中的cin.ignore()函数不适用于整个流
- 使用std::transform将一个范围的元素添加到另一个范围中
- 在基于范围的for循环中使用结构化绑定声明
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- Problems with std::cin.fail()
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 为左值和右值的包装器实现C++范围
- 尝试对字符串[数组]>>cin 并出现错误(" "字符串下标超出范围")
- 代码块编译错误.Cin 未在此范围内声明
- "字符串"/"cin"未在此范围内声明
- 限制cin.操作符到特定范围
- CIN在一定范围内