正在尝试了解输入验证循环

Trying to learn about input validation loops

本文关键字:输入 验证 循环 了解      更新时间:2023-10-16

在这个输入验证while循环中,在调用控制台输出后显示cerr。它显示为"输入费率:$Invalid rate"例如:

Enter rate: $750
Enter rate: $Invalid Rate. 

它与do-while循环的作用相同。有什么建议或帮助吗?

#include <iostream>
using namespace std;
#define max_rate 50
#define max_hours 80
int main() {
// input validation loop (loops until input is valid)
double rate, hours;
cout << "enter rate: $";
cin >> rate;
cin.ignore();
while (rate > max_rate){
if (rate > max_rate){
cerr << "Invalid Rate." << endl;
}
cout << "enter rate: $";
cin >> rate;
}
do {
if (hours > max_hours) {
cerr << "Invalid hours." << endl;
}
cout << "enter hours: ";
cin >> hours;
}
while (hours > max_hours);

double pay = rate * hours;
cout << "$" << pay << endl;
return 0;

答案是,先读,第二次检查,第三次索赔。也就是说,

for (;;) { // the same as while(true)
cin >> rate;
if (rate is valid)
break;
cout << "Invalid raten";
}

不要毫无理由地混合使用coutcerrcout延迟输出,在内部缓冲器中累积数据,而cerr立即打印。(但是coutcin使用时刷新缓冲区;也可以显式调用cout.flush[或cout << flush](。

验证用户输入就是在每次输入后检查流错误状态。流错误状态由四个主要状态的位掩码组成:goodbit(无错误(、badbit不可恢复的错误(、failbitofbit。每个流状态可以通过相应的成员函数.good().bad().fail().eof()来检查,或者通过直接读取和检查std::basic_ios:rdstate来检查。

.eof().bad()都是不可恢复的,.fail()要求您在尝试下一次输入之前从输入流中删除导致失败的任何有问题的字符(或者将再次读取导致失败的同一输入(,然后使用.clear()成员函数清除流错误状态。

当接受用户输入时,一种稳健的方法将不断循环,要求用户提供正确的输入,发出足够的诊断来通知用户出了什么问题,并在下一次输入之前处理从流状态中清除任何failbit以及从输入流中清除任何冒犯或无关字符。该方法相当简单,只需进入一个连续循环,提示,检查流状态,在出现不可恢复错误时退出,.clear().fail()上显示流错误,验证输入是否在所需范围内,如果满足所有条件,则break显示循环,最后在开始下一次输入迭代之前将所有字符删除到行的末尾。

要读取您的rate,可以将其放在一起,类似于以下内容:

for (;;) {          /* loop continually until valid input is received */
std::cout << "nenter rate: $ " << std::flush;  /* prompt/flush */
if ( !(std::cin >> rate) ) {
/* if eof() or bad() (unrecoverable) break read loop */
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "  user canceled or unrecoverable stream error.n";
return 1;
}
else if (std::cin.fail()) {     /* if failbit */
std::cerr << "  error: invalid double input.n";
std::cin.clear();           /* clear failbit */
}
}
else if (rate > max_rate)   /* validate against max_rate */
std::cerr << "  rate entered exceeds max_rate (" << max_rate << ")n";
else    /* all checks passed, good input */
break;
/* empty any extraneous character to end-of-line */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
}

对于CCD_ 22也可以做完全相同的事情。您可以编写一个处理提示和验证的函数,以减少代码主体中的一些重复,但只需包含ratehours的验证循环就可以了。内容和验证是重要的组成部分。

添加一个简短的main(),完整的示例可以是:

#include <iostream>
#include <limits>
#define max_rate 50     /* good -- if you need a constant, #define one (or more) */
#define max_hours 80
int main (void) {
double rate, hours;
for (;;) {          /* loop continually until valid input is received */
std::cout << "nenter rate: $ " << std::flush;  /* prompt/flush */
if ( !(std::cin >> rate) ) {
/* if eof() or bad() (unrecoverable) break read loop */
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "  user canceled or unrecoverable stream error.n";
return 1;
}
else if (std::cin.fail()) {     /* if failbit */
std::cerr << "  error: invalid double input.n";
std::cin.clear();           /* clear failbit */
}
}
else if (rate > max_rate)   /* validate against max_rate */
std::cerr << "  rate entered exceeds max_rate (" << max_rate << ")n";
else    /* all checks passed, good input */
break;
/* empty any extraneous character to end-of-line */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
}
for (;;) {          /* loop continually until valid input is received */
std::cout << "nenter hours: " << std::flush;   /* prompt/flush */
if ( !(std::cin >> hours) ) {
/* if eof() or bad() (unrecoverable) break read loop */
if (std::cin.eof() || std::cin.bad()) {
std::cerr << "  user canceled or unrecoverable stream error.n";
return 1;
}
else if (std::cin.fail()) {     /* if failbit */
std::cerr << "  error: invalid double input.n";
std::cin.clear();           /* clear failbit */
}
}
else if (hours > max_hours) /* validate against max_hours */
std::cerr << "  hours entered exceeds max_hours (" << max_hours << ")n";
else    /* all checks passed, good input */
break;
/* empty any extraneous character to end-of-line */
std::cin.ignore (std::numeric_limits<std::streamsize>::max(), 'n');
}
double pay = rate * hours;
std::cout << "n$" << pay << 'n';
}

示例使用/输出

一旦你写了一个输入例程——试着打破它。故意输入坏的输入和在好值之后的额外外来输入,以确保你处理了输入的所有方面。不过,最低限度的运行可能是:

$ ./bin/validate_rate_hours
enter rate: $ 56 dollars
rate entered exceeds max_rate (50)
enter rate: $ I don't care I really want $50!!
error: invalid double input.
enter rate: $ 50
enter hours: 120 hours and 59 minutes and 59 seconds
hours entered exceeds max_hours (80)
enter hours: I really want 120:59:59!!
error: invalid double input.
enter hours: 80
$4000

理解和检查C++流错误状态是编写健壮的输入例程的关键。仔细看看,如果你有问题,请告诉我。