【问题标题】:C++ cin.ignore and getline in while loopC++ cin.ignore 和 getline 在 while 循环中
【发布时间】:2018-04-26 22:34:55
【问题描述】:

我对编程很陌生,在 while 循环中使用 getline 时遇到问题。当我计算课程变量时,第一个字母丢失了。摆脱 cin.ignore 会将其发送到无限循环中。

这是我目前所拥有的:

#include <iostream>
#include <string>
using namespace std;
int main (){
   string answer = "Yes";
   string course;

   while (answer == "Yes"){
      cin.ignore();
      cout<< "Enter a course name: ";
      getline (cin, course);
      cout<< course << endl;

      cout<< "Continue ('Yes' or 'No')? ";
      cin>> answer;
      cout<< answer << endl;
   }

   return 0;
}

【问题讨论】:

标签: c++


【解决方案1】:

ignore 移动到循环的底部。它用于删除 cin &gt;&gt; 运算符留在缓冲区中的换行符,因此您只有在使用 cin &gt;&gt; 后才需要它。

您还应该将参数传递给ignore 以忽略所有内容,直到您点击换行符,以防他们在行上输入的不仅仅是“是”或“否”。你可以这样做:

cin.ignore(numeric_limits<streamsize>::max(), '\n');

在此处查看一个工作示例:ideone

【讨论】:

  • 对于提出的基本问题,根本不需要cin.ignore()getline 提取并丢弃换行符
  • @jwm getline 确实可以,但提取运算符 (cin &gt;&gt;) 不会,which is why the ignore is necessary
  • 是的,我注意到@Gil Bates 答案中的风格混合......一个更好的答案
【解决方案2】:

如果您使用getline,请坚持使用getline。将其与流操作混合起来很容易搞砸。

#include <iostream>
#include <string>

int main() {
  std::string answer = "Yes";
  std::string course;

  while (answer == "Yes") {
    do {
      std::cout << "Enter a course name: ";
      std::getline(std::cin, course);
    } while (course == "");

    std::cout << course << '\n';

    do {
      std::cout << "Continue ('Yes' or 'No')? ";
      std::getline(std::cin, answer);
    } while (answer != "Yes" && answer != "No");

    std::cout << answer << '\n';
  }
}

【讨论】:

    【解决方案3】:

    我看到的问题是,当您删除 cin.ignore() 时,您会得到如下交互:

    输入课程名称:数学

    数学

    继续(“是”或“否”)?是的

    是的

    输入课程名称:

    继续(“是”或“否”)?是的 // 等等等等...

    第二次没有提示你输入类。 这是因为您用于提交信息的 Enter/Return 被 getline() 提取,它在它看到的第一个 '\n' 字符处停止。

    修复它的一种方法是在自定义输入之后使用 cin.ignore()。 请注意,如果从文件中读取,您应该在类输入后结束该行以获得与此处相同的结果。

      while (answer == "Yes"){
                                         // REMOVE cin.ignore() FROM HERE
          cout<< "Enter a course name: ";
          getline (cin, course);
          cout<< course << endl;
    
          cout<< "Continue ('Yes' or 'No')? ";
          cin>> answer;
          cout<< answer << endl;
    
          {    // THIS IS MORE EFFICIENT
               cin.ignore();                // ADD cin.ignore() HERE TO DISCARD '\n'
          }
    
          {   // THIS WORKS BETTER FOR HUMAN INPUT
              string dummy;
              getline (cin, dummy)          
          }
      }
    

    【讨论】:

    • 很好的答案,但不能容忍人为错误。如果出现拼写错误并且用户在回车前添加了一个空格怎么办?
    • 这是一个很好的观点。我想说 getline 是一个适合读取文件的函数,但实际上并不适合人工输入。另一种方法是再次调用 getline 而不是 cin.ignore() 但没有人愿意这样做:)
    • Getline 可以读取 cin,因为用户自然会逐行输入。但是,应首先解析所有用户输入的错误。
    猜你喜欢
    • 1970-01-01
    • 2014-11-22
    • 2019-05-08
    • 1970-01-01
    • 2019-06-16
    • 1970-01-01
    • 2017-03-29
    • 2020-10-20
    • 1970-01-01
    相关资源
    最近更新 更多