有条件地中断长输入序列

Conditionally Breaking A Long Sequence Of Inputs?

本文关键字:输入 中断 有条件      更新时间:2023-10-16

我一直在做一个个人项目。为了工作,它需要接受来自用户的大量(相对)数据,这些数据以4种不同类型的数据的形式提供给12个用户。因此,我有一长串类似这样的语句:

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;

等。

然而,偶尔可能只需要输入少于12个怪物的数据,例如5-6甚至1-2。我希望能够使用命令跳过输入部分到基于击键之类的代码的其余部分。例如,如果用户输入了5个怪物的数据,这就是他们所需要的,他们可以按反斜杠来跳过其余的输入序列。

我所说的是否有意义/是否有一个STL命令来做我正在寻找的事情?目前,这个过程不是循环的,但是如果它在循环中,退出它会更容易吗?我确实想过这样做:

while(cin.get() != '') {
   cout << 'n' << "Monster A's name is: ";
   cin >> nameA;
   //etc...
}

EDIT:上面的尝试构建,但是在输入所需的击键后,它快速且无休止地打印用户提示,而不接受数据。任何建议吗?我只想让它破裂,然后继续生活。我能有效地使用switch语句吗?

谢谢!

可以。您还可以使用EOF,它比''更通用。完成后,按Ctrl-D发送EOF,就完成了。这可以处理一些玩家输入""作为怪物名字的情况。

我刚刚测试了这组代码,它似乎是你想要的工作方式。当然,你必须修改它以适应你原来的应用程序。

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++;
}

您可以检查名称是否为,这不是用户友好的,但它工作

string name;
while (name != "\") {
    cout << 'n' << "Monster A's name is: ";
    cin >> name;
    cout << "Received " << name << 'n';
    if (name != "\") {
        // do something with name ...
    }
}

如果循环仍然无休止地循环,请参见如何刷新cin缓冲区?并尝试清除stdin缓冲区。

[edit]我修复了循环中的错误

我写了一些东西。

struct Monster {
string name;
bool roll;
float dex;
float mod;
float level;
Monster(void) :
  name(),
  roll(false),
  dex(0),
  mod(0),
  level(0) { }
};

bool getMonsterInformationFromStdin(int index, Monster& monster) {
  string end_char = "\";
  string name, roll, dex, mod, level;
  cout << 'n' << "Monster " << index << "'s name is: ";
  cin >> name;
  if (name.compare(end_char) == 0) return false;
  monster.name = name;
  cout << 'n' << "Monster " << index << " rolled: ";
  cin >> roll;
  if (roll.compare(end_char) == 0) return false;
  monster.roll = (roll[0] == 'y' || roll[0] == 'Y') ? true : false;
  cout << 'n' << "Monster " << index << "'s Dex is: ";
  cin >> dex;
  if (dex.compare(end_char) == 0) return false;
  monster.dex = atof(dex.c_str());
  cout << 'n' << "Monster " << index << "'s Mod is: ";
  cin >> mod;
  if (mod.compare(end_char) == 0) return false;
  monster.mod = atof(mod.c_str());
  cout << 'n' << "Monster " << index << "'s Level is: ";
  cin >> level;
  if (level.compare(end_char) == 0) return false;
  monster.level = atof(level.c_str());
  return true;
}

int main(int argc, char** argv) {
  int max_monsters = 10;
  for (int i = 0; i < max_monsters; i++) {
    Monster m;
    if( !getMonsterInformationFromStdin(i, m) ) break;
    string roll = m.roll ? "rolled" : "didn't roll";
    cout << m.name << " " << roll << " dex: " << m.dex << " mod: " << m.mod << " level: " << m.level << endl;
  }
  return 0;
}

我认为这个问题可以通过使用哨兵怪物的名字来解决,如下图所示。

const string SentinelName = "%^&";
while(true)
{
    cout << 'n' << "Monster A's name is(if u want to end, pls input %^&): ";
    cin >> nameA;
    if(strcmp(nameA, SentinelName.s_str())
        break;
    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;
}

希望这能解决你的问题。此外,给你的代码一点建议,你可以将怪物的属性,如名称,模式级别等封装到一个类中,这会使你的代码看起来更漂亮。