为什么两个 getline() 导致没有输入?
why do two getline() lead to no input?
我正在创建一个简单的登录程序。
#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时的结果:
如您所见,我无法输入用户名。在函数 showRegister()
中,当我在 getline(cin, user)
之前添加 cin.ignore()
时,结果如下:
据我了解,getline()
读取一行直到到达字符 \n
并跳过其余部分。那么为什么在这种情况下,两个连续的 getline()
命令(getline(cin, user)
和 getline(cin, pw)
导致我无法输入用户名?
事实是,如果缓冲区中存在某些内容,getline 会从缓冲区获取输入,否则它会向用户询问值。在您的代码中实际发生的是,一旦您为 select 输入不大于 3 的值,它就会在您为 select 输入一个值并输入(代表\n) 您按下的内容将存储在缓冲区中。所以知道当您为用户访问 getline 时,它会从缓冲区中看到“\n”,因为 getline 首先检查缓冲区,因此它会跳过值插入并且缓冲区被清空,现在当您访问用于密码的 getline 时,它会询问用户输入密码,因为缓冲区为空。
从格式化输入切换到未格式化输入后,总是会发生这种情况。喜欢从 std::cin >> select
到 std::getline
格式化输入将读取您的 integer
“select”,但不会读取以下 CR LF。 (您按下了回车键)。
要解决这个问题,你可以简单地写:
getline(cin >> std::ws, user);
std::ws
将首先消耗领先的白色 space。然后 std::getline
将按预期工作。
请阅读 here 关于 std::ws
并且不要忘记包括 <iomanip>
您的代码中存在更多严重错误。就像对“showMenu”的循环调用
我正在创建一个简单的登录程序。
#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时的结果:
如您所见,我无法输入用户名。在函数 showRegister()
中,当我在 getline(cin, user)
之前添加 cin.ignore()
时,结果如下:
据我了解,getline()
读取一行直到到达字符 \n
并跳过其余部分。那么为什么在这种情况下,两个连续的 getline()
命令(getline(cin, user)
和 getline(cin, pw)
导致我无法输入用户名?
事实是,如果缓冲区中存在某些内容,getline 会从缓冲区获取输入,否则它会向用户询问值。在您的代码中实际发生的是,一旦您为 select 输入不大于 3 的值,它就会在您为 select 输入一个值并输入(代表\n) 您按下的内容将存储在缓冲区中。所以知道当您为用户访问 getline 时,它会从缓冲区中看到“\n”,因为 getline 首先检查缓冲区,因此它会跳过值插入并且缓冲区被清空,现在当您访问用于密码的 getline 时,它会询问用户输入密码,因为缓冲区为空。
从格式化输入切换到未格式化输入后,总是会发生这种情况。喜欢从 std::cin >> select
到 std::getline
格式化输入将读取您的 integer
“select”,但不会读取以下 CR LF。 (您按下了回车键)。
要解决这个问题,你可以简单地写:
getline(cin >> std::ws, user);
std::ws
将首先消耗领先的白色 space。然后 std::getline
将按预期工作。
请阅读 here 关于 std::ws
并且不要忘记包括 <iomanip>
您的代码中存在更多严重错误。就像对“showMenu”的循环调用