有条不紊地打破一长串输入?

时间:2013-06-14 23:57:31

标签: c++ user-input cin

我有一个我一直在做的个人项目。为了工作,它需要从用户接受大量数据(相对),以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...
}

编辑:上述尝试构建,但在输入所需的击键后,它会快速无休止地打印用户提示而不接受数据。有什么建议?我想要的只是让它打破并继续前进。我可以有效地使用switch语句吗?

谢谢!

5 个答案:

答案 0 :(得分:2)

这可行。你也可以使用比“\”更通用的EOF。然后,当你完成后,按Ctrl-D发送EOF,你就完成了。当一些玩家输入'\'作为怪物的名字时,这会处理这种情况。

答案 1 :(得分:0)

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

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

如果循环仍然无休止地循环,请参考How do I flush the cin buffer?并尝试清除stdin缓冲区。

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

答案 2 :(得分:0)

我刚刚测试了这组代码,它似乎与你想要的一样。当然,您必须对其进行修改以适合您的原始应用程序。

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

为了合并怪物数量的限制,而不是将true参数传递给while循环,只需添加一个计数器来创建多少怪物并在该条件下中断:

int num_monsters = 0;
while (num_monsters <= 12) {
    ...
    num_monsters++;
}

希望这有帮助。

答案 3 :(得分:0)

这是我写的东西。

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

答案 4 :(得分: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;
}

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