You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

cin.ignore()首次循环未触发输入延迟的问题求助

问题描述

我正在和朋友复刻移动端饮酒游戏Picolo——原版APP的问题太腻,想自定义问题。程序预期流程是:先提示输入玩家数量,随机打乱问题顺序,逐个展示问题。我用cin.ignore()等待用户按回车后显示下一题,但除首次循环外其余都正常:输入玩家姓名后,前两个问题会直接一起打印,之后才恢复正常。

源代码
#include<iostream>
using std::cin;
using std::cout;
using std::endl;
#include<algorithm>
using std::random_shuffle;
#include<fstream>
using std::ifstream;
#include<cstdlib>
#include<string>
using std::string;
#include<time.h>
const int numQuestions = 19;
int vir6rounds;
bool activeVir6 = false;
int v6counter = 0;

void getQuestion(int questionNumber, string players[], int numPlayers);
int getRandom();

int main()
{
  srand(time(0));
  // 创建玩家姓名数组
  cout << "Enter \"quit\" to end game" << endl;
  cout << "How many players?" << endl;
  int numPlayers;
  cin >> numPlayers;
  cout << "Enter players' names: " << endl;
  string players[numPlayers];
  for (int i = 0; i < numPlayers; i++)
    cin >> players[i];
  bool loop = true;
  int qArray[numQuestions];
  // 填充问题索引数组
  for (int i = 0; i < numQuestions; i++)
  {
    qArray[i] = i;
  }
  while (loop)
  {
    // 每次循环重新打乱问题顺序
    random_shuffle(qArray, qArray + numQuestions);
    for (int i = 0; i < numQuestions; i++)
    {
      // 随机选择3个玩家
      random_shuffle(players, players + numPlayers);
      getQuestion(qArray[i], players, numPlayers);
      cin.ignore();                                                     // 问题出在这里
    }
    cout << "Game over; press enter to play again" << endl;
    cin.ignore();
  }
}

void getQuestion(int questionNumber, string players[], int numPlayers)
{

  if (activeVir6 == true)
  {
    v6counter++;
    if (v6counter == vir6rounds)
    {
      cout << "Pong loser can speak again." << endl;
      cin.ignore();
      activeVir6 = false;
      v6counter = 0;
    }
  }
  string player1 = players[0];
  string player2 = players[1];
  string player3 = players[2];
  switch (questionNumber)
  {
  case 0:
    cout << "Going around, Play rock paper scissors with the player to your left." << endl;
    cout << "Losers take two drinks." << endl;
    break;
  case 1:
    cout << player1 << ", who would win in a fight? " << player2 << " or " << player3 << "?";
    cin.ignore();
    cout << "Loser takes two drinks." << endl;;
    break;
  case 2:
    cout << player1 << " chooses the next song" << endl;
    break;
  case 3:
    cout << "Whoever took a shower the least recently has to take a drink" << endl;
    break;
  case 4:
    cout << player1 << ", take as many penalties as you want.";
    cin.ignore();
    cout << "However many you took, " << player2 << " has to take double." << endl;
    break;
  case 5:
    cout << "Everyone switch drinks to the left" << endl;
    break;
  case 6:
    cout << "virus: " << player1 << " versus " << player2 << " in pong." << endl;
    cout << "loser can't speak until otherwise" << endl;
    activeVir6 = true;
    vir6rounds = getRandom();
    break;
  case 7:
    cout << player1 << " take as many penalties as the youngest players age.\nIf you're the youngest, everyone else take 2." << endl;
    break;
  case 8:
    cout << player1 << ", buy " << player2 << " a red bull or take 15 penalties" << endl;
    break;
  case 9:
    cout << player1 << ", let " << player2 << " look through your snap memories or take 8 penalties" << endl;
    break;
  case 10:
    cout << player1 << " has to say yes to " << player2 << " for 5 minutes or take 8 penalties" << endl;
    break;
  case 11:
    cout << player1 << ", show off ur best cartwheel" << endl;
    break;
  case 12:
    cout << player1 << ", change clothes with " << player2 << " or they pick how many penalties you take" << endl;
    break;
  case 13:
    cout << player1 << ", pick someone new to go on aux or they take 5 penalties" << endl;
    break;
  case 14:
    cout << player1 << ", cook " << player2 << " a meal or take 9 penalties" << endl;
    break;
  case 15:
    cout << player1 << ", pick two people to shotgun" << endl;
    break;
  case 16:
    cout << player1 << ", let " << player2 << " paint ur nails or take 10 penalties" << endl;
    break;
  case 17:
    cout << player1 << ", every time you talk to " << player2 << " take 3 penalties until otherwise" << endl;
    break;
  case 18:
    cout << player1 << ", kill yourself or take a penalty." << endl;
    break;
  default:
    cout << "question has not been defined yet" << endl;
  }
  return;
}
示例输入输出
/*
Enter "quit" to end game
How many players?
7
Enter players' names:
john
kevin
mark
stacy
helen
jenna
dylan
helen, buy john a red bull or take 15 penalties
dylan chooses the next song

mark, let stacy look through your snap memories or take 8 penalties

helen has to say yes to mark for 5 minutes or take 8 penalties

Everyone switch drinks to the left
*/
解决方案

问题根源

用cin >>读取玩家数量和姓名时,输入结束后的换行符会留在输入缓冲区里。第一次执行cin.ignore()时,实际是忽略了这个残留的换行符,没有等待用户输入,直接进入下一次循环,导致两个问题连续打印。

修复步骤

  1. 清空输入缓冲区残留的换行符:
    首先在代码开头包含<limits>头文件:
    #include <limits>
    
    然后在输入完所有玩家姓名的循环后,添加代码清空缓冲区:
    cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
    
  2. 统一处理等待逻辑:代码里getQuestion函数内部也有cin.ignore()(比如case1、case4),这些会和主循环的等待重复,导致需要按两次回车。可以二选一:
    • 去掉主循环里的cin.ignore(),只保留函数内的等待逻辑;
    • 去掉函数内的cin.ignore(),统一用主循环的等待。

新手友好小建议

  • 避免使用变长数组(string players[numPlayers];),C++标准不支持这种写法,换成std::vector<std::string>更安全:
    #include <vector>
    // ...
    std::vector<std::string> players(numPlayers);
    
  • 你声明了getRandom()函数但没实现,运行会报错,补一个简单实现:
    int getRandom() {
        return rand() % 5 + 1; // 生成1-5的随机数,可按需调整范围
    }
    

内容的提问来源于stack exchange,提问作者scumjag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 23:30:48