如果我想限制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;
}
答案 0 :(得分:1)
您可以尝试这样的事情:
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);
答案 1 :(得分:0)
在这种情况下,一些运算符重载可以隐藏可重用辅助类的复杂性:
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 low\n";
}
else if (dest > the_limits.upper_limit) {
std::cout << "Value too high\n";
}
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 */ }
答案 2 :(得分:0)
您可以创建一个为您执行此操作的操纵器:
#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);
}
答案 3 :(得分:0)
除了我的另一个答案,这是设置范围的另一种方法,但将语义合并到流的语言环境中安装的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...
}