避免错误的用户输入(当要求的是整数时为字符串)
Avoid bad user input (string when what's asked is an integer)
我有一个无限循环,要求用户输入一个数字。
我的问题很简单:如果输入是一个字符串,我想重新要求用户输入,输出消息"Enter a valid choice: "。
我搜索过,看起来我应该检查 cin.fail()
,然后调用 cin.clear()
和 cin.ignore()
。
这是我的代码:
int main() {
int choice;
bool failed = false;
while (true) {
if (failed) cout << "Enter a valid choice: ";
else cout << "Enter a number: ";
cin >> choice;
if (cin.fail()) {
cin.clear();
cin.ignore();
failed = true;
}
}
return 0;
}
但是,这并不能真正解决我的问题。当然,它不是无限打印,但是对于每个字母 extra letter ,它会打印另一个 "Enter a valid choice:"
似乎我需要为每个额外的字母调用 cin.ignore()
。
还有其他方法吗?
你有一个无限循环,因为即使输入有效输入你也没有打破循环。那是你真正想要的吗?如果是这样,至少,您没有在有效输入中重置 failed
标志。
更重要的是,当输入无效输入时,您并没有忽略输入的所有内容,您一次只忽略 1 个字符。这就是您看到额外提示的原因。
试试这个:
int main() {
int choice;
while (true) {
cout << "Enter a number: ";
while (!(cin >> choice)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Enter a valid choice: ";
}
}
return 0;
}
它打印这么多次的原因是因为你只是清除了cin的状态,而没有清除输入缓冲区。您可以通过多种方式这样做:-
使用fflush(stdin)
清除输入buffer.This是C的方法,可以通过包含cstdio来完成header.
使用cin.ignore忽略当前输入流中的所有字符。您可以通过将忽略单个字符的行 cin.ignore()
替换为忽略整行的代码 cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
来实现。为此,您需要限制 header.
最后你可以用像 while (cin.get() != '\n'){continue;}
这样的简单循环来做同样的事情,它忽略所有字符直到换行。
还有另一种解决相同问题的方法是采用字符串形式的输入并使用 strtol()
或 isdigit()
函数来检查输入是否有效。
对了死循环是因为你没有使用break语句终止循环。所以你可以通过添加
来避免这种情况
if(!failed)
break;
还需要通过添加
来更改每个循环入口处的 Failed 状态
failed=false;
在循环开始时 body。
我有一个无限循环,要求用户输入一个数字。
我的问题很简单:如果输入是一个字符串,我想重新要求用户输入,输出消息"Enter a valid choice: "。
我搜索过,看起来我应该检查 cin.fail()
,然后调用 cin.clear()
和 cin.ignore()
。
这是我的代码:
int main() {
int choice;
bool failed = false;
while (true) {
if (failed) cout << "Enter a valid choice: ";
else cout << "Enter a number: ";
cin >> choice;
if (cin.fail()) {
cin.clear();
cin.ignore();
failed = true;
}
}
return 0;
}
但是,这并不能真正解决我的问题。当然,它不是无限打印,但是对于每个字母 extra letter ,它会打印另一个 "Enter a valid choice:"
似乎我需要为每个额外的字母调用 cin.ignore()
。
还有其他方法吗?
你有一个无限循环,因为即使输入有效输入你也没有打破循环。那是你真正想要的吗?如果是这样,至少,您没有在有效输入中重置 failed
标志。
更重要的是,当输入无效输入时,您并没有忽略输入的所有内容,您一次只忽略 1 个字符。这就是您看到额外提示的原因。
试试这个:
int main() {
int choice;
while (true) {
cout << "Enter a number: ";
while (!(cin >> choice)) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
cout << "Enter a valid choice: ";
}
}
return 0;
}
它打印这么多次的原因是因为你只是清除了cin的状态,而没有清除输入缓冲区。您可以通过多种方式这样做:-
使用
fflush(stdin)
清除输入buffer.This是C的方法,可以通过包含cstdio来完成header.使用cin.ignore忽略当前输入流中的所有字符。您可以通过将忽略单个字符的行
cin.ignore()
替换为忽略整行的代码cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
来实现。为此,您需要限制 header.最后你可以用像
while (cin.get() != '\n'){continue;}
这样的简单循环来做同样的事情,它忽略所有字符直到换行。
还有另一种解决相同问题的方法是采用字符串形式的输入并使用 strtol()
或 isdigit()
函数来检查输入是否有效。
对了死循环是因为你没有使用break语句终止循环。所以你可以通过添加
来避免这种情况if(!failed)
break;
还需要通过添加
来更改每个循环入口处的 Failed 状态failed=false;
在循环开始时 body。