为什么std :: cin不会对此窒息? [英] Why doesn't std::cin choke on this?

查看:51
本文介绍了为什么std :: cin不会对此窒息?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,当我为数据结构编写用户驱动的测试程序时,我写了一个恼人的问题。测试程序布局为

菜单,其中包含多个编号选项。用户通过键入

其相应的数字(int)来选择一个选项。根据他的选择,他可能会被要求提供另一个整数(或根本没有输入)。所以所有用户都会输入
进入整数。我不希望用户通过提供无效输入来导致问题或

崩溃,但他尽管我的错误检查。

以下是我的输出程序在这里归结为最小:

$ ./test

1 - 选择一个

2 - 选择二

3 - 退出计划

你有什么选择? 1

输入整数加倍:2 + 2

2加倍是4

1 - 选择一个

2 - 选择2

3 - 退出计划

你有什么选择?输入要求平方的整数:


在此测试运行中,用户在被询问菜单时询问他想要的选项时按1。但当被要求输入一个整数时,他输入2 + 2,并且cin没有

进入错误状态,但留下最后一个''2'加上流中的换行符,

触发一个新的菜单选项('+''被cin.get()调用吃掉了

应该摆脱换行符。现在我该如何修复我的代码所以它

不允许这个?为什么当被要求输入

整数时,为什么不会在2 + 2上窒息?


#include< iostream>

#include< limits>

#include< string>


int enter_integer(const std :: string& prompt);


int main()

{

std ::字符串提示;


while(true)

{

std :: cout<<" 1 - 选择一个<<< std :: endl;

std :: cout<<" 2 - choice two"<< std :: endl;

std :: cout<<" 3 - 退出程序"<< std :: endl;


int n = enter_integer("你有什么选择? );


开关(n)

{

案例1:

n = enter_integer (输入要加倍的整数:);


std :: cout<< n<< "加倍是 << n * 2<< std :: endl;


休息;

案例2:

n = enter_integer("输入整数待平方:" ;);


std :: cout<< n<< "平方是 << n * n<< std :: endl;


休息;

案例3:

返回0;

默认:

std :: cout<< n<< "是一个无效的菜单选择。 << std :: endl;

}

}

}


int enter_integer(const std: :string& prompt)

{

while(true)

{

std :: cout<< ;提示<< std :: flush;


int n;


std :: cin>> n;


if(!std :: cin)

{

std :: cin.clear();

std :: cin.ignore(std :: numeric_limits< std :: streamsiz e> :: max(),

''\ n'');


std :: cout<< 你必须输入一个整数! << std :: endl;

}

else

{

std :: cin.get(); / *摆脱流中的换行符。 * /


返回n;

}

}


返回-1 ; / *永远不应该达成。 * /

}


/ William Payne

Hello, when I was writing a user-driven test program for a data structure I
wrote, I encountered an annoying problem. The test program is laid out as a
menu with several numbered options. The user selects one option by typing in
its corresponding number (int). Depending on the choice he made, he may be
asked to provide another integer (or no input at all). So all the user does
is entering integers. I don''t want the user to be able to cause problems or
crashes by providing invalid input, but he is despite my error checking.
Here follows output from my program here boiled down to a "minimum":
$ ./test
1 - choice one
2 - choice two
3 - exit program
What is your choice? 1
Enter integer to be doubled: 2+2
2 doubled is 4
1 - choice one
2 - choice two
3 - exit program
What is your choice? Enter integer to be squared:

In this test run the user presses 1 when asked for which choice he wants in
the menu. But when asked to input an integer he enters 2+2, and cin does not
go into an error state but leaves the last ''2'' plus a newline in the stream,
triggering a new menu option (the ''+'' was eaten by a call to cin.get() which
is supposed to get rid of the newline. Now how can I fix my code so it
doesn''t allow this? And why doesn''t cin choke on 2+2 when asked to enter an
integer?

#include <iostream>
#include <limits>
#include <string>

int enter_integer(const std::string& prompt);

int main()
{
std::string prompt;

while(true)
{
std::cout << "1 - choice one" << std::endl;
std::cout << "2 - choice two" << std::endl;
std::cout << "3 - exit program" << std::endl;

int n = enter_integer("What is your choice? ");

switch(n)
{
case 1:
n = enter_integer("Enter integer to be doubled: ");

std::cout << n << " doubled is " << n * 2 << std::endl;

break;
case 2:
n = enter_integer("Enter integer to be squared: ");

std::cout << n << " squared is " << n * n << std::endl;

break;
case 3:
return 0;
default:
std::cout << n << " is an invalid menu choice." << std::endl;
}
}
}

int enter_integer(const std::string& prompt)
{
while(true)
{
std::cout << prompt << std::flush;

int n;

std::cin >> n;

if(!std::cin)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsiz e>::max(),
''\n'');

std::cout << "You must enter an integer!" << std::endl;
}
else
{
std::cin.get(); /* Get rid of newline in the stream. */

return n;
}
}

return -1; /* Should never be reached. */
}

/ William Payne

推荐答案

./ test

1 - 选择一个

2 - 选择两个

3 - 退出计划

你有什么选择? 1

输入整数加倍:2 + 2

2加倍是4

1 - 选择一个

2 - 选择2

3 - 退出计划

你有什么选择?输入要求平方的整数:


在此测试运行中,用户在被询问菜单时询问他想要的选项时按1。但当被要求输入一个整数时,他输入2 + 2,并且cin没有

进入错误状态,但留下最后一个''2'加上流中的换行符,

触发一个新的菜单选项('+''被cin.get()调用吃掉了

应该摆脱换行符。现在我该如何修复我的代码所以它

不允许这个?为什么当被要求输入

整数时,为什么不会在2 + 2上窒息?


#include< iostream>

#include< limits>

#include< string>


int enter_integer(const std :: string& prompt);


int main()

{

std ::字符串提示;


while(true)

{

std :: cout<<" 1 - 选择一个<<< std :: endl;

std :: cout<<" 2 - choice two"<< std :: endl;

std :: cout<<" 3 - 退出程序"<< std :: endl;


int n = enter_integer("你有什么选择? );


开关(n)

{

案例1:

n = enter_integer (输入要加倍的整数:);


std :: cout<< n<< "加倍是 << n * 2<< std :: endl;


休息;

案例2:

n = enter_integer("输入整数待平方:" ;);


std :: cout<< n<< "平方是 << n * n<< std :: endl;


休息;

案例3:

返回0;

默认:

std :: cout<< n<< "是一个无效的菜单选择。 << std :: endl;

}

}

}


int enter_integer(const std: :string& prompt)

{

while(true)

{

std :: cout<< ;提示<< std :: flush;


int n;


std :: cin>> n;


if(!std :: cin)

{

std :: cin.clear();

std :: cin.ignore(std :: numeric_limits< std :: streamsiz e> :: max(),

''\ n'');


std :: cout<< 你必须输入一个整数! << std :: endl;

}

else

{

std :: cin.get(); / *摆脱流中的换行符。 * /


返回n;

}

}


返回-1 ; / *永远不应该达成。 * /

}


/ William Payne
./test
1 - choice one
2 - choice two
3 - exit program
What is your choice? 1
Enter integer to be doubled: 2+2
2 doubled is 4
1 - choice one
2 - choice two
3 - exit program
What is your choice? Enter integer to be squared:

In this test run the user presses 1 when asked for which choice he wants in
the menu. But when asked to input an integer he enters 2+2, and cin does not
go into an error state but leaves the last ''2'' plus a newline in the stream,
triggering a new menu option (the ''+'' was eaten by a call to cin.get() which
is supposed to get rid of the newline. Now how can I fix my code so it
doesn''t allow this? And why doesn''t cin choke on 2+2 when asked to enter an
integer?

#include <iostream>
#include <limits>
#include <string>

int enter_integer(const std::string& prompt);

int main()
{
std::string prompt;

while(true)
{
std::cout << "1 - choice one" << std::endl;
std::cout << "2 - choice two" << std::endl;
std::cout << "3 - exit program" << std::endl;

int n = enter_integer("What is your choice? ");

switch(n)
{
case 1:
n = enter_integer("Enter integer to be doubled: ");

std::cout << n << " doubled is " << n * 2 << std::endl;

break;
case 2:
n = enter_integer("Enter integer to be squared: ");

std::cout << n << " squared is " << n * n << std::endl;

break;
case 3:
return 0;
default:
std::cout << n << " is an invalid menu choice." << std::endl;
}
}
}

int enter_integer(const std::string& prompt)
{
while(true)
{
std::cout << prompt << std::flush;

int n;

std::cin >> n;

if(!std::cin)
{
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsiz e>::max(),
''\n'');

std::cout << "You must enter an integer!" << std::endl;
}
else
{
std::cin.get(); /* Get rid of newline in the stream. */

return n;
}
}

return -1; /* Should never be reached. */
}

/ William Payne


William Payne写道:
William Payne wrote:

您好,当我为数据结构编写用户驱动的测试程序时,我写道,我遇到了一个烦人的问题。测试程序布局为带有多个编号选项的菜单。用户通过键入其对应的数字(int)来选择一个选项。


这是你的问题。你读了一个int。

你能做的最简单的事就是忘记读int的想法。

毕竟,如果用户输入2,这就是一个字符就像''a''或''b''。

所以读取所有内容作为字符,然后更简单然后检查流'

状态,获取摆脱无效输入,清除错误状态,从而

使流再次可用。

根据他的选择,他可能会被要求提供另一个整数(或根本没有输入)。


当你尝试读取int时,完全没有输入是很棘手的。再说一遍:如果你用字符串读取
,这就变得微不足道了。

所以所有用户都在输入整数。我不希望用户通过提供无效输入来引起问题或崩溃,但他尽管我的错误检查仍然存在。
以下是我的程序的输出,这里归结为最小的:

Hello, when I was writing a user-driven test program for a data structure I
wrote, I encountered an annoying problem. The test program is laid out as a
menu with several numbered options. The user selects one option by typing in
its corresponding number (int).
And this is your problem. You read an int.
The simplest thing you can do is to forget the idea of reading an int.
After all, if the user types 2, this is a character just like ''a'' or ''b''.
So read everything as character, it simpler then checking the stream for it''s
state, getting rid of the invalid input, clearing that error state and thus
make the stream workable again.
Depending on the choice he made, he may be
asked to provide another integer (or no input at all).
Having no input at all is tricky when you try to read an int. Again: If you
read in a string, this becomes trivial.
So all the user does
is entering integers. I don''t want the user to be able to cause problems or
crashes by providing invalid input, but he is despite my error checking.
Here follows output from my program here boiled down to a "minimum":


./ test
1 - 选择一个
2 - 选择2
3 - 退出程序
什么是你的选择吗? 1
输入整数加倍:2 + 2
2加倍是4
1 - 选择一个
2 - 选择2
3 - 退出程序
你的选择是什么?输入要求平方的整数:

在此测试运行中,用户在询问菜单中要求的选项时按1。但当被要求输入一个整数时他输入2 + 2,并且cin没有进入错误状态


为什么要这样?

定义流定义为尽可能多地读取

请求。请求是读取一个int,因此所有可以是int

的都是从流中获取的,在你的情况下是第一个''2'。其余的留在

输入队列中,等待你的程序读取它。

但留下最后一个''''加上流中的换行符,
触发一个新的菜单选项('+''是通过调用cin.get()来吃掉的,
应该摆脱换行符。现在我该如何修复我的代码呢
不允许这样做?


查找流的ignore()函数。

但是再次,它更简单to * not *将用户输入作为int读取。将其作为字符串读取,

然后尝试从字符串中提取数字。这样用户可以输入更多

他喜欢(甚至根本没有数字),没有什么特别的事情会发生:用户输入

被读作字符串而你的号码检测功能将无法提取

a数字,因此你的程序会发出错误。但是在任何情况下

流都没有进入失败状态,必须再次使用(额外的) cting

来自字符串的东西,字符串流是一个方便的工具。)

当被要求进入
整数?
./test
1 - choice one
2 - choice two
3 - exit program
What is your choice? 1
Enter integer to be doubled: 2+2
2 doubled is 4
1 - choice one
2 - choice two
3 - exit program
What is your choice? Enter integer to be squared:

In this test run the user presses 1 when asked for which choice he wants in
the menu. But when asked to input an integer he enters 2+2, and cin does not
go into an error state
why should it?
Streams are defined that they try to read as much as possible to fullfil the
request. The request was to read an int, thus everything that can be an int
is taken from the stream, in your case the first ''2''. The rest is left in the
input queue and is waiting for your program to read it.
but leaves the last ''2'' plus a newline in the stream,
triggering a new menu option (the ''+'' was eaten by a call to cin.get() which
is supposed to get rid of the newline. Now how can I fix my code so it
doesn''t allow this?
look up the ignore() function of the stream.
But again, it''s simpler to *not* read the users input as an int. Read it as a string,
then try to extract the number from the string. This way the user can enter whetever
he likes (even no ''numer'' at all), and nothing special will happen: The users input
is read as string and your number detection function will not be able to extract
a number from that and thus your program will emit an error. But in no case the
stream has entered a fail state and must be made useable again (for extracting
something from a string, the stringstreams are a handy tool).
And why doesn''t cin choke on 2+2 when asked to enter an
integer?




见上文。它被定义为那样。如果您输入了:''* 2''它会因为''*''不是一个整数的有效起始字符而被扼住了。


-

Karl Heinz Buchegger
kb******@gascad.at


这篇关于为什么std :: cin不会对此窒息?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆