C++ 为什么std::getline()在格式化提取后跳过输入?
我有以下代码提示用户输入他们的猫的年龄和名字:C++ 为什么std::getline()在格式化提取后跳过输入?,c++,input,iostream,istream,c++-faq,C++,Input,Iostream,Istream,C++ Faq,我有以下代码提示用户输入他们的猫的年龄和名字: #include <iostream> #include <string> int main() { int age; std::string name; std::cin >> age; std::getline(std::cin, name); if (std::cin) { std::cout << "My
#include <iostream>
#include <string>
int main()
{
int age;
std::string name;
std::cin >> age;
std::getline(std::cin, name);
if (std::cin)
{
std::cout << "My cat is " << age << " years old and their name is " << name << std::endl;
}
}
为什么输出中省略了名称?我已经给出了正确的输入,但是代码忽略了它。为什么会发生这种情况?为什么会发生这种情况?
这与您自己提供的输入无关,而是与默认行为std::getline()
has有关。当您为age(std::cin>>age
)提供输入时,您不仅提交了以下字符,而且在键入Enter时,还向流追加了一个隐式换行符:
从终端提交时,选择“输入”或“返回”时,始终会在输入后追加换行符。它还用于文件中,用于移动到下一行。在提取到age
之后,换行符保留在缓冲区中,直到下一个I/O操作将其丢弃或读取。当控制流达到std::getline()
时,它将看到“\nMr.wiskers”
,并且将丢弃开头的换行符,但输入操作将立即停止。发生这种情况的原因是因为std::getline()
的任务是尝试读取字符,并在找到新行时停止。因此,其余的输入将留在缓冲区中未读
解决方案
cin.ignore()
要解决此问题,一个选项是在执行std::getline()
之前跳过换行符。您可以通过在第一次输入操作后调用std::cin.ignore()
来完成此操作。它将丢弃下一个字符(换行符),使其不再碍事
std::cin >> age;
std::cin.ignore();
std::getline(std::cin, name);
匹配操作
当您遇到这样的问题时,通常是因为您将格式化输入操作与未格式化输入操作相结合。格式化输入操作是指接受输入并将其格式化为特定类型。这就是operator>>()
的作用。无格式输入操作是除此之外的任何操作,如std::getline()
,std::cin.read()
,std::cin.get()
,等等。这些函数不关心输入的格式,只处理原始文本
如果您坚持使用单一格式,则可以避免此恼人的问题:
// Unformatted I/O
std::string age, name;
std::getline(std::cin, age);
std::getline(std::cin, name);
或
如果您选择使用未格式化操作将所有内容作为字符串读取,则可以在以后将其转换为适当的类型。为什么会发生这种情况?
这与您自己提供的输入无关,而是与默认行为std::getline()
has有关。当您为age(std::cin>>age
)提供输入时,您不仅提交了以下字符,而且在键入Enter时,还向流追加了一个隐式换行符:
从终端提交时,选择“输入”或“返回”时,始终会在输入后追加换行符。它还用于文件中,用于移动到下一行。在提取到age
之后,换行符保留在缓冲区中,直到下一个I/O操作将其丢弃或读取。当控制流达到std::getline()
时,它将看到“\nMr.wiskers”
,并且将丢弃开头的换行符,但输入操作将立即停止。发生这种情况的原因是因为std::getline()
的任务是尝试读取字符,并在找到新行时停止。因此,其余的输入将留在缓冲区中未读
解决方案
cin.ignore()
要解决此问题,一个选项是在执行std::getline()
之前跳过换行符。您可以通过在第一次输入操作后调用std::cin.ignore()
来完成此操作。它将丢弃下一个字符(换行符),使其不再碍事
std::cin >> age;
std::cin.ignore();
std::getline(std::cin, name);
匹配操作
当您遇到这样的问题时,通常是因为您将格式化输入操作与未格式化输入操作相结合。格式化输入操作是指接受输入并将其格式化为特定类型。这就是operator>>()
的作用。无格式输入操作是除此之外的任何操作,如std::getline()
,std::cin.read()
,std::cin.get()
,等等。这些函数不关心输入的格式,只处理原始文本
如果您坚持使用单一格式,则可以避免此恼人的问题:
// Unformatted I/O
std::string age, name;
std::getline(std::cin, age);
std::getline(std::cin, name);
或
如果您选择使用未格式化操作将所有内容作为字符串读取,则可以在以后将其转换为适当的类型。如果您以以下方式更改初始代码,则所有内容都将正常:
if ((cin >> name).get() && std::getline(cin, state))
如果您以以下方式更改初始代码,一切都将正常:
if ((cin >> name).get() && std::getline(cin, state))
发生这种情况的原因是,当终端通知流开始新行时,会将一个隐式换行符(也称为换行符)追加到终端的所有用户输入中。您可以在检查多行用户输入时使用来安全地说明这一点。
std::getline
的默认行为将从输入流对象(在本例中为std::cin
)中读取所有内容,包括换行符\n
#include <iostream>
#include <string>
int main()
{
std::string name;
std::string state;
if (std::getline(std::cin, name) && std::getline(std::cin, state))
{
std::cout << "Your name is " << name << " and you live in " << state;
}
return 0;
}
发生这种情况的原因是,当终端通知流开始新行时,会将一个隐式换行符(也称为换行符)追加到终端的所有用户输入中。您可以在检查多行用户输入时使用来安全地说明这一点。
std::getline
的默认行为将从输入流对象(在本例中为std::cin
)中读取所有内容,包括换行符\n
#include <iostream>
#include <string>
int main()
{
std::string name;
std::string state;
if (std::getline(std::cin, name) && std::getline(std::cin, state))
{
std::cout << "Your name is " << name << " and you live in " << state;
}
return 0;
}
因为上面的每个人都回答了输入
10\n\r\n
的问题,所以我想回答一个不同的方法。上面的所有解决方案都发布了缓冲区是否为li的代码
string StringInput() //returns null-terminated string
{
string input;
getline(cin, input);
while(input.length()==0)//keep taking input until valid string is taken
{
getline(cin, input);
}
return input.c_str();
}
#include <iostream>
#include <string>
int main()
{
int age;
std::string name;
std::cin >> age;
name = StringInput();
std::cout << "My cat is " << age << " years old and their name is " << name << std::endl;
}
//instead of "std::cin>>age;" use "get_untill_int(&age);" in main function.
void get_Untill_Int(int* pInput)//keep taking input untill input is `int or float`
{
cin>> *pInput;
/*-----------check input validation----------------*/
while (!cin)
{
cin.clear();
cin.ignore(100, '\n');
cout<<"Invalid Input Type.\nEnter again: ";
cin >>*pInput;
}
/*-----------checked input validation-------------*/
}