无法根据字符提前中断用户输入?
Can't Break From User Input Early Based On Character?
我有一个问题是从我之前的一个问题(有条件地打破长序列的输入?)演变而来的,但到目前为止,没有人能够给我一个满意的答案,我所有的努力都失败了。
如果用户不需要的话,我试图让他们尽早打破输入。例如,对于下面的代码:
cout << 'n' << "Monster A's name is: ";
cin >> nameA;
cout << 'n' << "Monster A rolled: ";
cin >> rollM_A;
cout << 'n' << "Monster A's Dex is: ";
cin >> DexA;
cout << 'n' << "Monster A's Mod is: ";
cin >> ModA;
cout << 'n' << "Monster A's Level is: ";
cin >> LvlA;
//etc.
实际上最多支持12个怪物。如果用户只想使用其中的3-4个,我希望他们能够跳过其余的,从而节省大量的按键次数。我已经确保将所有变量初始化为0,并有一个函数稍后从存储向量中删除0个元素。所缺少的就是远离这个输入链。我尝试过各种形式的while循环包装,像这样:
while(cin.get() != '#') {
cout << 'n' << "Monster A's name is: ";
cin >> nameA;
//etc...
}
但是在输入所需字符时,代码只是一遍又一遍地输出所有提示("怪物A的名字是:"等),而不继续前进或接受进一步的输入。这就像代码被困在一个无限循环中,即使它应该在# input时离开循环。
任何想法?我真的被这个问题困了一段时间,如果有人能提供一个替代的解决方案,或者至少让我知道我自己的缺陷,我将非常感激。
谢谢!
这段代码引发了一个无限循环,因为std::cin的操作符>>不接受"行结束"字符(回车键),所以它仍然在流中。
所以当你第二次到达cin.get()时,缓冲区中仍然有一个字符(从你验证怪物的名字时输入)。cin.get()接受它,看看它不是'#',然后转到下一个std::cin,它们做同样的事情。可以通过忽略char:
来修复此行为。while(cin.get() != '#')
{
cout << 'n' << "Monster A's name is: ";
cin >> nameA;
//etc...
cin.ignore();
}
我刚刚测试了这组代码,它似乎是你想要的工作方式。当然,你必须修改它以适应你原来的应用程序。
std::string in;
while (true) {
std::cout << "Enter a namen";
std::cin >> in;
if (in == "#")
break;
std::cout << "nMonster A's name is: " << in << "n";
}
为了结合怪物数量的限制,而不是将true
参数传递到while循环中,只需添加一个计数器来显示创建了多少怪物并在该条件下中断:
int num_monsters = 0;
while (num_monsters <= 12) {
...
num_monsters++;
}
面向对象和标准库:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class Monster {
string name;
int rolled, dex, mod, level;
template<class input, class output, class container>
friend input& read_monster(input& i, output& o, container &c) {
string n;
o << "nMonster's name is: " << flush;
i >> n;
if( !i || (n == "#") ) {
o << "nEnd of monster list";
i.setstate(ios::failbit);
return i;
}
Monster m;
m.name = n;
o << "nMonster's rolled is " << flush;
i >> m.rolled;
if( !i ) return i;
o << "nMonster's dex is " << flush;
i >> m.dex;
if( !i ) return i;
o << "nMonster's mod is " << flush;
i >> m.mod;
if( !i ) return i;
o << "nMonster's level is " << flush;
i >> m.level;
if( !i ) return i;
o << "n";
c.push_back(m);
return i;
}
template<class output>
friend output& operator<<(output& o, Monster&m) {
return o << "Monster('" << m.name <<"', R/" << m.rolled
<< ", D/" << m.dex << ", M/" << m.mod << ", L/" << m.level
<< ")n";
}
Monster() : name(), rolled(), dex(), mod(), level() {}
};
int main(int, char**) {
vector<Monster> v;
while( read_monster(cin, cout, v) && (v.size() <= 12) )
;
for( auto m: v )
cout << m;
return 0;
}
既然你在做面向行的输入,你真的应该使用std::getline
读取。由于有直线方向的输入由行块组成,每个行块定义一个对象,您应该创建一个类,并读取它。(另外,你还需要更多的错误处理,因为您需要处理)
显然,每一个关注点都应该被分成一个单独的函数:
std::string
getLineFromPrompt( std::string const& prompt )
{
std::string results;
std::cout << prompt;
std::getline( std::cin, results );
return results;
}
template <typename T>
bool
tryGetValueFromPrompt( std::string const& prompt, T& value )
{
std::string line = getLineFromPrompt( prompt );
std::istringstream parser( line );
return parser >> value >> std::ws && parser.get() == EOF;
}
template <typename T>
void
getValueFromPrompt( std::string const& prompt, T& value )
{
while ( ! tryGetValueFromPrompt( prompt, value ) ) {
std::cout << "Illegal input, try again" << std::endl;
}
}
class Monster
{
std::string name;
int roll;
int dexterity;
int mod;
int level;
public:
Monster( std::string const& name )
: name( name )
{
getValueFromPromt( name + " rolled:", roll );
getValueFromPromt( name + " dexterity:", dexterity );
getValueFromPromt( name + " mod:", mod );
getValueFromPromt( name + " level:", level );
}
};
bool
isEndFlag( std::string const& line )
{
return line.empty() || line[0] == '#';
}
最后,循环:
std::vector <Monster> monsters;
std::string nextName = getLineFromPrompt();
while ( ! isEndFlag( nextName ) ) {
monsters.push_back( Monster( nextName ) );
nextName = getLineFromPrompt();
}
正如您所看到的,将每个单独的关注点分解为一个单独的函数会产生更简单的代码。
你能计算信息吗?'按#跳过这个问题'?而不是让用户猜测跳过问题的哪个键?
- C++如何通过用户输入删除列表元素
- 创建一个函数以在输入为负数或零时输出字符串.第一次执行用户定义的函数
- 如何使用用户输入在C++中正确填充2D数组
- C++MySQL C api用户输入行
- 使用用户定义函数的字符串反转
- 用户定义函数中的指针和输入
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 如何只允许用户输入正整数
- C++如何计算用户输入的数字中的偶数位数
- 通过for循环使用用户输入填充列表
- 这是我尝试让用户将值输入到数组中.然后将其隐藏为大量的星号
- 在C++中,我如何接受不同于同一行的用户输入
- 当用户超过按钮点击限制时报告
- Visual C++(VS2017)中用户定义的转换不明确
- 如何在 Linux 用户空间中处理类似 GPIO 中断的处理
- C++等待用户输入的中断线程
- BeagleBone Black从用户空间获得中断
- 无法根据字符提前中断用户输入?
- 在没有用户输入输入的情况下中断while循环
- 在用户输入时中断,否则继续