我正在使用get.fail()来检查输入中是否有任何字符,如果有,我想给用户一个重新输入的机会。但是,无论哪种情况,只要输入前面有一个整数,该程序似乎仍会接受用户输入。假设w1
和1w
,该程序将告诉用户,它仅接受整数,而后者接受输入并移至下一行,然后引起另一个问题。
void userChoice(int input){
switch(input)
{
case 1:
insert();
break;
case 2:
display();
break;
case 3:
update_data();
break;
case 4:
delete_position();
break;
case 5:
cout<<"Thank you for using the program\n";
exit(0);
break;
case 6:
tellSize();
break;
default:
cout<<"Not an option\n";
cin>>input;
while(cin.fail())
{
cin.clear();
cin.ignore(INT_MAX, '\n');
cin>>input;
break;
}
userChoice(input);
}
}
参考上面的代码,说我输入了1w
。程序仍然会执行情况1,就好像没有什么问题,然后w
会以某种方式传递到insert()
函数中,这不是我想要的。我希望该程序无论是1w
还是w1
都允许用户重新输入,总之,如果有字符,我不希望程序移至下一行。整数输入。
tl; dr:
为什么当cin为1w
时,下面的代码仍然可以执行,为什么不打印“仅输入数字”,因为其中有一个字符?
编辑:这是我制作的一个快速程序,要重现我所遇到的错误,我首先输入1h
,这是我所遇到的第一个错误,为什么在有字符{{ 1}}中输入?然后在第二个输入中,我输入h
并打印出2w
,由于输入中有一个字符2
,该程序是否应该循环while循环?
w
答案 0 :(得分:1)
从您的评论看来,您似乎只需要整数输入,并且即使1w
可能是1
也不想允许在诸如int
这样的整数后面输入其他字符。转换为w
的同时,.ignore(...)
仍未读取,将在您调用.clear()
之后由.clear()
删除。 (如上所述,您现在对.ignore(...)
和.peek()
的使用是正确的。
如果这是您的意图,则需要一种方法来检查用户输入的整数后面是否还有其他内容。要在不存在任何障碍的情况下以非阻塞方式进行操作,则有两种选择。 (例如,您可以在下一个字符string
处输入字符-但您只能得到一个字符,或者可以使用 line _ 输入法) line _ 该方法允许您将整个用户输入行读入getline()
,然后提取整数值并检查输入行中是否还包含其他任何内容。
最直接的方法是从用void menu()
读取的数据行中创建一个std::basic_stringstream。这种方法消耗了整个用户输入行,并为您提供了从行中提取任何所需信息所需的所有工具。这样做也不会影响您以后的任何用户输入。
虽然我建议您结合使用void options(int input)
和menu()
函数,以便仅使用一个函数来处理菜单的输入处理-将它分成两部分并没有什么错,除了可能性重复的几行代码。以下只是有关如何处理#include <sstream>
#include <string>
函数以仅允许整数输入的建议。您可以使其适应代码的其余部分。
您将需要几个附加条件:
#define
我也会#define MENUFIRST 1 /* first valid entry */
#define MENULAST 1 /* last valid entry */
接受第一个和最后一个菜单项,因此您可以在代码中使用这些常量,并且可以在添加菜单时轻松更改这些常量,例如
1
(注意:,仅允许输入menu()
作为有效菜单项)
要使用上述方法来限制您void menu(){
int user_input = 0;
string line, unwanted;
for (;;) { /* loop continually until valid input received */
cout << "\nEnter 1 to print something: ";
if (!getline (cin, line)) { /* read an entire line at a time */
cerr << "(user canceled or unrecoverable stream error)\n";
return;
}
stringstream ss (line); /* create a stringstream from line */
if (!(ss >> user_input)) { /* test if valid integer read */
/* test eof() or bad() */
if (ss.eof() || ss.bad()) /* if not, did user cancel or err */
cerr << "(empty-input or unreconverable error)\n";
else if (ss.fail()) /* if failbit - wasn't an int */
cerr << "error: invalid integer input.\n";
}
else if (ss >> unwanted) { /* are there unwanted chars? */
cerr << "error: additional characters following user_input.\n";
user_input = 0; /* reset user_input zero */
} /* was int outside MENUFIRST-to-MENULAST? */
else if (user_input < MENUFIRST || MENULAST < user_input)
cerr << "error: integer not a valid menu selection.\n";
else /* valid input!, break read loop */
break;
}
options(user_input);
}
的功能,可以执行以下操作:
// bool fail;
鉴于以上讨论,这些评论应该是不言自明的,但是如果您有任何疑问,请告诉我。将该功能与其余代码一起使用(并注释未使用的$ ./bin/menu_int
Enter 1 to print something: w1
error: invalid integer input.
Enter 1 to print something: $#%&^#&$ (cat steps on keyboard) !#$%%^%*()
error: invalid integer input.
Enter 1 to print something: 1w
error: additional characters following user_input.
Enter 1 to print something: -1
error: integer not a valid menu selection.
Enter 1 to print something: 24
error: integer not a valid menu selection.
Enter 1 to print something: 1
Enter the amount of cake
3
3
),您可以测试它是否满足您的要求,例如
使用/输出示例
menu()
还请注意,您的EOF
函数现在将正确捕获用户按下 Ctrl + d (或 Ctrl + z 在Windows上)取消输入并正常退出。