vny*_*lng 2 c++ validation iostream goto istream
我有以下代码:
qstn:
cout << "Input customer's lastname: ";
getline(cin, lname);
if (lname.find_first_not_of("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ") != string::npos) {
cout << "You can only input alpha here!\n";
cin.clear();
goto qstn;
} else if (lname.empty()) {
cout << "Please enter your firstname!\n";
cin.clear();
goto qstn;
}
int lnamel = lname.length();
int strl = str.length();
int is = 0;
for (int i = 1; i < strl;) {
i++;
is++;
if (lname[i] == lname[is] && lname[i] == ' ' || lname[0] == ' ') {
cin.clear();
cout << "Please input your lastname properly!\n";
goto qstn;
}
}
// next question here
Run Code Online (Sandbox Code Playgroud)
我很难想到什么是避免goto语句的正确逻辑,因为我上大学时我正在使用它,但是有人说这根本不好用,因为它可能会破坏我的代码.
我尝试使用do while循环,但它并不像goto那样流畅.
请帮忙!
这是我喜欢用的习语:
int i;
if (std::cin >> prompt("enter an integer: ", i))
{
std::cout << "Read user input: " << i << "\n";
} else {
std::cout << "Input failed (too many attempts). Eof? " << std::boolalpha << std::cin.eof() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
这里prompt是一个智能输入操纵器,负责处理解析错误或流故障并重试.
它非常通用,所以实际上做了很多事情,但你不需要指出所有选项.当操纵器插入流中时,它会传递给do_manip成员:
template <typename Char, typename CharT>
friend std::basic_istream<Char, CharT>& operator>>(std::basic_istream<Char, CharT>& is, checked_input<T, Prompter>& manip) {
return manip.do_manip(is);
}
Run Code Online (Sandbox Code Playgroud)
在do_manip处理所有的逻辑,没有任何goto小号 :):
std::istream& do_manip(std::istream& is) {
auto attempt = [this] { return infinite() || retries_ > 0; };
while (attempt()) {
if (!infinite())
retries_ -= 1;
prompter_(out_);
if (is >> value_) {
if (!run_validators(out_))
is.setstate(is.rdstate() | std::ios::failbit);
else
break;
} else {
out_.get() << format_error_ << "\n";
}
if (attempt()) {
is.clear();
if (flush_on_error_)
is.ignore(1024, '\n');
}
}
return is;
}
Run Code Online (Sandbox Code Playgroud)
您可以看到在接受输入之前可以运行验证.
这是一个有点全面的演示:
int main() {
using namespace inputmagic;
int i;
if (std::cin >> prompt("enter an integer: ", i)
.retries(3)
.flush_on_error(false)
.format_error("I couldn't read that (Numbers look like 123)")
.output(std::cerr)
.validate([](int v) { return v > 3 && v < 88; }, "value not in range (3,88)")
.validate([](int v) { return 0 == v % 2; })
.validate([](int v) { return v != 42; }, "The Answer Is Forbidden")
.multiple_diagnostics())
{
std::cout << "Read user input: " << i << "\n";
} else {
std::cout << "Input failed (too many attempts). Eof? " << std::boolalpha << std::cin.eof() << "\n";
}
}
Run Code Online (Sandbox Code Playgroud)
你可以看到它只接受有效的整数
在随后的重试中输入数字21,42和10时,您会得到:live
enter an integer: 21
Value not valid
enter an integer: 42
The Answer Is Forbidden
enter an integer: 10
Read user input: 10
Run Code Online (Sandbox Code Playgroud)
但是,如果你一直输入1:live
enter an integer: 1
value not in range (3,88)
Value not valid
enter an integer: 1
value not in range (3,88)
Value not valid
enter an integer: 1
value not in range (3,88)
Value not valid
Input failed (too many attempts). Eof? false
Run Code Online (Sandbox Code Playgroud)
或者,如果您从单行文件中读取:live
enter an integer: value not in range (3,88)
Value not valid
enter an integer: I couldn't read that (Numbers look like 123)
enter an integer: I couldn't read that (Numbers look like 123)
Input failed (too many attempts). Eof? true
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
849 次 |
| 最近记录: |