我正在介绍C ++类,我想知道一种更好的检查输入是否是所需类型的方法。
这是一个很好的方法吗?我来自PHP / PERL背景,这使我非常担心使用while循环。
char type;
while (true) {
cout << "Were you admitted? [y/n]" << endl;
cin >> type;
if ((type == 'y') || (type == 'n')) {
break;
}
}
这是安全这样做的方式还是我打开了一个受伤的世界,我怀疑?什么是更好的方法,以确保我在继续之前得到我想要的输入?
答案 0 :(得分:25)
就我个人而言:
do
{
cout << "Were you admitted? [y/n]" << endl;
cin >> type;
}
while( !cin.fail() && type!='y' && type!='n' );
答案 1 :(得分:9)
就个人而言,我会将提示作为一个单独的函数,这使得它将提示输出和读取响应作为逻辑表达式放入while循环中。
测试读取是否成功对于代码的正确运行至关重要。
我还希望一次使用std::getline
来获取一行,因为它有助于减少因读取半数读取行的剩余部分而导致的错误,这是部分读取早期用户响应的结果。
bool PromptForChar( const char* prompt, char& readch )
{
std::string tmp;
std::cout << prompt << std::endl;
if (std::getline(std::cin, tmp))
{
// Only accept single character input
if (tmp.length() == 1)
{
readch = tmp[0];
}
else
{
// For most input, char zero is an appropriate sentinel
readch = '\0';
}
return true;
}
return false;
}
void f()
{
char type = '\0';
while( PromptForChar( "Were you admitted? [y/n]", type ) )
{
if (type == 'y' || type == 'n')
{
// Process response
break;
}
}
}
答案 2 :(得分:4)
使用可以使用
do {
program;
} while (condition_to_repeat);
如果算法类似于您的示例。否则该示例是“安全的”,但我不确定可读性。
答案 3 :(得分:2)
为什么不这样做?
do
{
cout << "Were you admitted? [y/n]" << endl;
cin >> type;
}while( type !='y' && type !='n');
答案 4 :(得分:1)
没关系。如果您希望在发生多次失败后超时,可以使用i<10
但不值得。
答案 5 :(得分:1)
不要忘记让潜在用户的生活更容易解释每一步,甚至提供不区分大小写的输入。
#include <iostream>
#define MAX_USER_INPUT_ATTEMPTS 3
int _tmain(int argc, _TCHAR* argv[])
{
char input_value = ' ';
int current_attempt = 1;
while(true)
{
std::cout << "Please confirm your choice (press y[es] or n[o] and Enter): ";
std::cin >> input_value;
input_value = tolower( input_value );
if(input_value=='y' || input_value=='n')
{
break;
}
else
{
std::cout << "You have used " << current_attempt << " of " << MAX_USER_INPUT_ATTEMPTS << " attempts" << std::endl;
++current_attempt;
}
if( current_attempt > MAX_USER_INPUT_ATTEMPTS )
{
std::cout << "Warning: Maximum number of attempts reached." << std::endl;
break;
}
}
return 0;
}
答案 6 :(得分:1)
基于行的输入不必冗长,您可以使用您编写一次的单个函数将其设为succinct,但仍处理极端情况:
bool yesno_repeat(char const* prompt) {
using namespace std;
while (true) {
cout << prompt << " [yn] ";
string line;
if (!getline(cin, line)) {
throw std::runtime_error("unexpected input error");
}
else if (line.size() == 1 and line.find_first_of("YyNn") != line.npos) {
return line == "Y" || line == "y";
}
}
}
int main() try {
if (yesno_repeat("Blow up?")) {
take_off_every<Zig>(); // in the future, a zig is a nuclear missile...
}
return 0;
}
catch (std::exception& e) {
std::cerr << e.what() << '\n';
return 1;
}
答案 7 :(得分:1)
这是一个更短的方式
char type;
while (type != 'y')
{
cout << "Were you admitted? [y/n]" << endl;
cin >> type;
}
答案 8 :(得分:0)
我以前从未在PERL / PHP中编码,而是基于您的问题,这里的示例是一个简单的解决方案。
char c;
while(true){
cout << "Were you admitted? [y/n]" << endl;
cin >> c;
if(c == 'y')
break;
}
cin.get(c);
return 0;
在输入“y”后输入“y”将继续提示您,此简单程序将退出。
答案 9 :(得分:0)
do ... while构造是为此做的,但你也可以在循环条件下完成所有工作:
while (std::cout << "Were you admitted [y/n]\n" && std::cin >> answer && !(answer == 'y' || answer == 'n'));
:)
如果你不想测试std::cin >> answer
的成功(例如想要用Ctrl + Z无限循环),你可以用逗号替换&&
:)
并非完全严重,即使将提示置于条件中,有时可以增强此类循环的逻辑(避免中断)。
答案 10 :(得分:0)
我在这里看到两个“问题”。第一个是使用while(true)。我不认为这是一个很好的做法(虽然这可能是许多人的品味问题)。然而,在循环中打破对搜索很有意义:
for(i = 0; i < MAX; ++i) {
if ( v[ i ] == searchedElement ) {
break;
}
}
这是不言自明的:你一直运行到向量的末尾,但是如果找到了元素,你就会在到达之前中断。这是合理的。
关于从控制台获取信息,直接从cin读取会遇到很多麻烦,例如,如果输入有内容,则只返回第一个空格。 getline()是一个实用程序函数,它读取一个字符串,它几乎总是安全的。 getline()在实用程序标头中定义。您还需要字符串标题。如果您想使用EOF,请使用cstdio。
int main()
{
int ch;
std::string type;
do {
getline( std::cin, type );
if ( cin.fail() ) {
ch = EOF;
break;
}
ch = tolower( type[ 0 ] );
} while( ch != 'y' && ch != 'n' );
// interesting things here...
return 0;
}
答案 11 :(得分:0)
修改@McAden所说的内容,尝试修复错误,如果输入多个字符,测试只检查第一个字母。
char type;
char buffer[128];
do
{
cout << "Were you admitted? [y/n]" << endl;
cin >> buffer;
type = buffer[0];
cout << type << "\n";
}while( !cin.fail() && type!='y' && type!='n' );
答案 12 :(得分:0)
这是提示y / n的另一种方式。 &#34;虽然&#34;你没有得到你想要的东西,&#34;切换&#34;在你的输入。做任何你喜欢的事情;它只是有效。
#include "stdafx.h"
#include <iostream>
int main()
{
bool play = true; // Initialize play to true.
char choice;
while (play) // While play is true, do the following:
{
std::cout << "Play again? [y/n] -> ";
std::cin >> choice;
switch (choice)
{
case 'n': // We can fall through here because we
play = false; // don't do anything with 'y' anyway.
case 'y': // Remember; play is already true unless
break; // we changed it to false with 'n'.
default: // We'll simply assume anything else is a fail!
std::cin.clear();
std::cin.ignore(1024, '\n');
break;
}
// Break out here and check the "while" condition again...
}
// When play becomes false, we exit the while statement.
}
这没有任何不利的后遗症!
答案 13 :(得分:0)
提示y / n的另一种方法。 “做”这个“而”你没有得到你想要的东西。做任何你喜欢的事情;它只是有效。
#include "stdafx.h"
#include <iostream>
int main()
{
bool accepted;
char answer;
do
{ // Ask for 'y' or 'n' at least once
std::cout << "Accepted? [y/n] -> ";
std::cin >> answer;
if (std::cin.fail())
{ // not a valid character?
std::cin.clear();
std::cin.ignore(1024, '\n');
}
if (answer == 'n')
{ // character is 'n'?
accepted = false;
}
else
{ // character is 'y'?
accepted = true;
}
// not valid |or| not 'n' |or| not 'y'
} while (std::cin.fail() || !(answer == 'n') || !(answer == 'y'));
}
这也没有不良的后遗症!
答案 14 :(得分:0)
char yn;
bool choice;
do
{
cout<<"Would you like try again?\n";
cout<<"Y for yes N for no: ";
cin>>yn;
while (yn != 'n'&& yn != 'N'&&yn != 'y'&&yn != 'Y')
{
cout<<"Y or N please: ";
cin>>yn;
}
if (yn == 'n'||yn == 'N')
choice = false;
if(yn == 'y'||yn == 'Y')
choice = true;
} while (choice == true);