C++ Can';不能根据字符提前中断用户输入?

C++ Can';不能根据字符提前中断用户输入?,c++,user-input,conditional-statements,cin,C++,User Input,Conditional Statements,Cin,我有一个问题是从我以前的一个()发展而来的,但到目前为止,没有人能给我一个满意的答案,我所有的努力都失败了 我试图允许用户在不需要输入的情况下提前中断输入。i、 例如,对于以下代码: cout << '\n' << "Monster A's name is: "; cin >> nameA; cout << '\n' << "Monster A rolled: "; cin >> rollM_A; cout <<

我有一个问题是从我以前的一个()发展而来的,但到目前为止,没有人能给我一个满意的答案,我所有的努力都失败了

我试图允许用户在不需要输入的情况下提前中断输入。i、 例如,对于以下代码:

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.
coutnamea;
不能滚动;
cout-DexA;
库特莫达;
cout-LvlA;
//等等。
最多支持12个怪物。如果用户只想使用,比如说,3-4个,我希望他们能够跳过其余的,并为自己节省大量的击键次数。我已经确保将所有变量初始化为0,并且有一个函数可以在以后从存储向量中删除0个元素。所缺少的就是远离这个输入链。我尝试过各种形式的while循环包装,如下所示:

while(cin.get() != '#') {
   cout << '\n' << "Monster A's name is: ";
   cin >> nameA;
   //etc...
}
while(cin.get()!='#'){
不能命名;
//等等。。。
}
但在输入所需的字符时,代码只是一次又一次地输出所有提示(“怪物A的名字是:”,等等),而不继续或接受进一步的输入。这就像代码卡在无限循环中,即使它应该在输入时离开循环

有什么想法吗?我真的被困在这个问题上有一段时间了,如果有人能提供一个替代的解决方案,或者至少让我知道我自己的缺陷,我将非常感激


谢谢

你能说出信息吗,例如“按#跳过这个问题”?不要让用户猜测跳过该问题的键?

你能说出信息吗,例如“按#跳过该问题”?我没有让用户猜测跳过这个问题的键是什么?

我只是测试了这组代码,它似乎按照您的意愿工作。当然,您必须修改它以适合您的原始应用程序

std::string in;

while (true) {
    std::cout << "Enter a name\n";
    std::cin >> in;
    if (in == "#")
        break;
    std::cout << "\nMonster A's name is: " << in << "\n";
}

希望这能有所帮助。

我刚刚测试了这组代码,它似乎按照您的意愿工作。当然,您必须修改它以适合您的原始应用程序

std::string in;

while (true) {
    std::cout << "Enter a name\n";
    std::cin >> in;
    if (in == "#")
        break;
    std::cout << "\nMonster A's name is: " << in << "\n";
}

希望这能有所帮助。

您的代码片段会引发无限循环,因为std::cin的运算符>>没有使用“行尾”字符(回车键),所以它仍然在流中

因此,当您第二次到达cin.get()时,缓冲区中仍然有一个字符(在验证怪物名称时输入)。cin.get()接受它,查看它不是“#”,然后转到下一个std::cin,它也会这样做。您可以通过忽略字符来修复此行为:

while(cin.get() != '#')
{
   cout << '\n' << "Monster A's name is: ";
   cin >> nameA;
   //etc...
   cin.ignore();
}
while(cin.get()!='#')
{
不能命名;
//等等。。。
cin.ignore();
}

您的一段代码会引发一个无限循环,因为std::cin的运算符>>没有使用“行尾”字符(回车键),所以它仍然在流中

因此,当您第二次到达cin.get()时,缓冲区中仍然有一个字符(在验证怪物名称时输入)。cin.get()接受它,查看它不是“#”,然后转到下一个std::cin,它也会这样做。您可以通过忽略字符来修复此行为:

while(cin.get() != '#')
{
   cout << '\n' << "Monster A's name is: ";
   cin >> nameA;
   //etc...
   cin.ignore();
}
while(cin.get()!='#')
{
不能命名;
//等等。。。
cin.ignore();
}

面向对象和stdlib的救援:

#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;
类怪物{
字符串名;
整数滚动,dex,mod,level;
模板
朋友输入与读取怪物(输入与输入、输出与输出、容器与c){
字符串n;
奥恩;
如果(!i | |(n==“#”)){

o面向对象和stdlib的救援:

#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;
类怪物{
字符串名;
整数滚动,dex,mod,level;
模板
朋友输入与读取怪物(输入与输入、输出与输出、容器与c){
字符串n;
奥恩;
如果(!i | |(n==“#”)){

o既然你在做面向行的输入,你真的应该这样做 使用
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::string
getLineFromPrompt(标准::字符串常量和提示符)
{
std::字符串结果;
std::cout>value>>std::ws&&parser.get()==EOF;
}
模板
无效的
getValueFromPrompt(标准::字符串常量和提示符,T和值)
{
而(!tryGetValueFromPrompt(prompt,value)){

std::cout既然你在做面向行的输入,你真的应该这样做 使用
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::string
getLineFromPrompt(标准::字符串常量和提示符)
{
std::字符串结果;
std::cout>value>>std::ws&&parser.get()==EOF;
}
模板
无效的
getValueFromPrompt(标准::字符串常量和提示符,T和值)
{
而(!tryGetValueFromPrompt(prompt,value)){

std::这不能解决所有的运营问题,一旦我开始工作,我可以,也会。我也不想只跳过一个,而是整个输入列表的其余部分。这不能解决所有的运营问题。一旦我开始工作,我可以,也会。我也不想只跳过一个,而是跳过整个输入列表的其余部分。这不起作用k对我来说。不幸的是,行为是一样的。附加:为此目的使用cin.clear()提供了一些有趣的行为!列表不是无休止地滚动,而是滚动一次,然后返回到被#打破的位置,然后停止。这让我很感兴趣。我觉得我现在可能很接近了。明白了!cin.clear()和cin.ignore()现在唯一的问题是(v