为什么两个 getline() 导致没有输入?

why do two getline() lead to no input?

提问人:trangan 提问时间:9/18/2021 更新时间:9/18/2021 访问量:67

问:

我正在创建一个简单的登录程序。

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

void showRegister()
{
    string user;
    string pw;
    cout << "Enter your username:";
    getline(cin, user);
    cout << "Enter your password:";
    getline(cin, pw);
    cout << "You have successfully registered!" << endl;
    writeIntoFile(user, pw);
    showMenu();
}
void showMenu() {
    int select;
    do {
        cout << "1. Register"<<endl;
        cout << "2. Login" << endl;
        cout << "3. Exit" << endl;
        cout << "Enter your choice: ";
        cin >> select;
    } while (select > 3);

    switch (select)
    {
    case 1:
        showRegister();
        break;
    case 2:
        showLogin();
        break;
    case 3:
    default:
        break;
    }
}

int main()
{
    showMenu();
    return 0;
}

这是我选择 1 时的结果:enter image description here

如您所见,我无法输入用户名。在函数中,当我添加之前时,结果是这样的:showRegister()cin.ignore()getline(cin, user)enter image description here

据我了解,阅读一行直到它到达字符并跳过其余部分。那么为什么在这种情况下,两个连续的命令(并导致我无法输入用户名?getline()\ngetline()getline(cin, user)getline(cin, pw)

C++ 输入 IOSTREAM getline

评论

0赞 drescherjm 9/18/2021
我认为问题出在您的菜单上,这是:https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction
0赞 trangan 9/18/2021
@drescherjm:谢谢你的回答。我已经准备好了那篇文章。但我不认为它回答了我的问题。此外,获得最多赞成票的用户建议我们应该使用 .我认为这就是我在这里使用的,但它导致没有输入......std::string age, name; std::getline(std::cin, age); std::getline(std::cin, name);
2赞 ol202020 9/18/2021
这是因为您添加了一个隐藏字符,即 CR LF(在 Windows 中:'\n' '\r')。因此,当您调用 showRegister 并调用 getline() 时,它将获取上一个命令 (1) 的 CR LF 字符,而不是用户名输入

答:

2赞 NIKhil kumar 9/18/2021 #1

事实是,如果缓冲区中存在某些内容,getline 会从缓冲区获取输入,否则它会向用户询问值。代码中实际发生的情况是,只要您输入不大于 3 的 select 值,它就会从循环中出来,然后您为 select 输入一个值,并且您按下的输入值(代表 \n)将存储在缓冲区中。所以要知道,当你来到用户的getline时,它会从缓冲区中看到'\n'作为getline首先签入缓冲区,所以它跳过了值插入,缓冲区被清空,现在当你来到用于密码的getline时,它会要求用户输入密码,因为缓冲区是空的。

评论

0赞 trangan 9/19/2021
谢谢!现在我明白了我的问题。有好的一天!:)
0赞 A M 9/19/2021
对不起,我需要学习英语。我几乎无法理解你的回答。也许你可以改写一下?
2赞 A M 9/18/2021 #2

从格式化输入切换到非格式化输入后,将始终发生这种情况。喜欢从 到std::cin >> selectstd::getline

格式化的输入将读取您的“select”,但不会读取以下 CR LF。(您按了回车键)。integer

要解决这个问题,您可以简单地编写:

    getline(cin >> std::ws, user);

std::ws将首先消耗前导空白。然后将按预期工作。std::getline

请阅读此处,不要忘记包括std::ws<iomanip>

您的代码中存在更严重的错误。就像对“showMenu”的 cicrular 调用一样

评论

0赞 trangan 9/19/2021
谢谢! 对我来说其实是新的。它按预期工作。我仍然不清楚为什么你说循环呼叫是一个问题。这实际上是我想要做的。我希望在注册或登录后,我们回到主菜单。cin >> std::wsshowMenu