【问题标题】:Program not waiting for cin程序不等待 cin
【发布时间】:2012-08-29 15:10:21
【问题描述】:
int x=0;
string fullname = "";
float salary;
float payincrease;
float newsal;
float monthlysal;
float retroactive;
while(x<3){
    cout << "\n What is your full name?";
    cin >> fullname;
    cout << "\n What is your current salary? \t";
    cin >> salary;
    cout << "\n What is your pay increase? \t";
    cin >> payincrease;
    newsal = (salary*payincrease)+salary;
    monthlysal = newsal/12.00;
    retroactive = (monthlysal*6)-(salary/2);
    cout << "\n" << fullname << "'s SALARY INFORMATION";
    cout << "\n New Salary \t Monthly Salary \t Retroactive Pay";
    cout << "\n \t" << newsal << "\t" << monthlysal << "\t" << retroactive;
    x++;
}

每次询问 cin 时,我的循环似乎都不会停止,而是立即自行执行循环 3 次。当询问输入时如何让它停止?

【问题讨论】:

  • cin 停在空格处。如果您一次输入一个单词,它将正常工作。否则,使用std::getline
  • 您绝不能编写未立即在布尔上下文中捕获的输入操作。否则,无法说明您的程序将如何进行。没有必要再看下去了。
  • @chris, cin 本身并不会专门在空格处“停止”; operator&gt;&gt;(istream&amp;,string&amp;) 默认情况下会这样做。
  • @eq-,我很欣赏你的迂腐。你是对的,当然。 cin 只是一个对象。
  • @chris *pedantry(因为你很欣赏它)——无法抗拒。

标签: c++ loops input console


【解决方案1】:

如果调用 cin 时输入流不为空,则 cin 会使用缓冲区中已有的数据,而不是等待用户提供更多数据。您正在使用提取运算符,因此当 cin 向您的变量发送值时,它会跳过缓冲区中的前导空格并在下一个空格处停止。

在这一行放一个断点:

cout << "\n What is your current salary? \t";

运行程序,然后输入 Bob Smith。当您到达断点时,将光标悬停在您的字符串全名上。你会看到它只存储“Bob”而不是“Bob Smith”。 “Bob Smith”被放入缓冲区,但是当您将 cin 与提取运算符一起使用时,它会跳过任何前导空格,将找到的下一个值放入您的变量中,然后在下一个空格处停止。为了证明这一点,请尝试运行:

#include <iostream>
#include <string>
using namespace std;
int main()
{
    string str1,str2;
    cin >> str1;
    cin >> str2;
    cout << str1 << " " << str2 << "\n\n";
    return 0;
}

如果您输入“Bob Smith”,即使您调用 cin 两次,它也只会输入一次。但是,您会看到“Bob”和“Smith”都被字符串 str1 和 str2 捕获。

因此,您可以得出结论,当 cin 到达 Bob 和 Smith 之间的空格时,它会停止填充您的字符串全名。在您下次调用 cin 时,缓冲区仍包含“Smith”,因此它不会从用户那里获取更多输入,而是尝试用“Smith”填充您的可变薪水。显然这不是你想要做的。您可以在每次使用 cin 之前在 cin 上调用 flush 和 ignore 以清除缓冲区,或者您可以修复您的逻辑并使用 getline 获取全名,包括空格。

要解决您的问题,您需要做的就是使用 getline 而不是 cin >>,因此替换此行:

cin >> fullname;

用这个:

getline(cin,fullname,'\n');

其次,您正在使用 while 循环来执行一组操作特定次数。这通常是你会使用 for 循环的东西。

顺便说一句,您还可以编写微小的输入验证循环,以帮助您调试或避免尝试将无效输入放入变量(例如“Smith”放入浮点数)。像这样的东西可以工作:

for(;;)
{
    if(cin >> salary)
        break;
    cin.clear();
    cin.ignore(INT_MAX,'\n');
}

请注意 cin 返回一个值,因此您可以在 if 语句中使用它。如果它得到有效的输入,它将返回 true。如果不是,它将返回 false。为了使其更明确,您也可以只使用不带 if 语句的正常调用 cin,然后检查 if cin.good(),这相当于基本相同的净效果。如果您没有使用 Visual Studio 并收到有关 INT_MAX 的错误,您可能需要 #include limits.h 来解决它。

【讨论】:

  • 请注意,使用 getline() 时,需要注意输入缓冲区中剩余的空白。特别是,任何 '\n' 字符都会导致下次使用 operator&lt;&lt;() 看起来像是被忽略了。
  • @Code-Guru,你指的是 cin.getline 对吧?在我使用的 getline 中没有这种危险。 cin
  • grr ...您可能是对的。自从我定期编写 C++ 以来已经太久了。我想在回答这样的问题之前我需要回顾一下这些东西......
  • 是的,cin 有一些奇怪的地方,一旦你学会在控制台窗口中编程,它就没有足够的习惯来真正重要。
  • 没错。而且我显然目前对哪些功能情况感到困惑......
【解决方案2】:

如果您输入 char 而需要 int,就会发生这种情况。

使用cin.clear();cin.ignore(numeric_limits&lt;streamsize&gt;::max(), '\n'); 将输入限制为仅限int

除此之外,如果输入正确的数据类型,它不会跳过。

#include <string>
#include <iostream>
#include <limits>
using namespace std ;



int main(void)
{


    int x=0;
    string fullname = "";
    float salary;
    float payincrease;
    float newsal;
    float monthlysal;
    float retroactive;

    while(x<3)
    {
        cout << "\n What is your full name?";
        cin >> fullname;
    cin.ignore( 1000, '\n' );

        cout << "\n What is your current salary? \t";
        cin >> salary;
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

        cout << "\n What is your pay increase? \t";
        cin >> payincrease;
    cin.clear();
    cin.ignore(numeric_limits<streamsize>::max(), '\n');

        newsal = (salary*payincrease)+salary;
        monthlysal = newsal/12.00;
        retroactive = (monthlysal*6)-(salary/2);
        cout << "\n" << fullname << "'s SALARY INFORMATION";
        cout << "\n New Salary \t Monthly Salary \t Retroactive Pay";
        cout << "\n \t" << newsal << "\t" << monthlysal << "\t" << retroactive;
        x++;
    }


      cout<<" \nPress any key to continue\n";
      cin.ignore();
      cin.get();

   return 0;
}

【讨论】:

    【解决方案3】:

    检查您的变量类型,我注意到我的变量类型接受数字而不是字符,遇到了同样的问题(没有停止,循环一直在继续)。

    > std::cin >> this->controls.button
    
    > DETOX_NUMBER button; // (int) 
    

    改为:

    > char button;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-20
      • 1970-01-01
      • 2017-05-03
      • 2018-06-01
      • 1970-01-01
      • 2023-03-10
      • 2014-06-30
      • 2012-01-24
      相关资源
      最近更新 更多