为什么会出现这种情况?
This has little to do with the input you provided yourself but rather with the default behavior std::getline()
has. When you provided your input for the age (std::cin >> age
), you not only submitted the following characters, but also an implicit newline was appended to the stream when you typed Enter:
"10\n"
A newline is always appended to your input when you select Enter or Return when submitting from a terminal. It is also used in files for moving toward the next line. The newline is left in the buffer after the extraction into age
until the next I/O operation where it is either discarded or read. When the flow of control reaches std::getline()
, it will see "\nMr. Whiskers"
and the newline at the beginning will be discarded, but the input operation will stop immediately. The reason this happens is because the job of std::getline()
is to attempt to read characters and stop when it finds a newline. So the rest of your input is left in the buffer unread.
Solution
cin.ignore()
要解决此问题,一种选择是在执行之前跳过换行符std::getline()
。您可以通过致电来做到这一点std::cin.ignore()
第一次输入操作后。它将丢弃下一个字符(换行符),以便它不再妨碍。
std::cin >> age;
std::cin.ignore();
std::getline(std::cin, name);
assert(std::cin);
// Success!
std::ws
丢弃空格的另一种方法是使用std::ws
函数是一个操纵器,旨在从输入流的开头提取并丢弃前导空格:
std::cin >> age;
std::getline(std::cin >> std::ws, name);
assert(std::cin);
// Success!
The std::cin >> std::ws
表达式在之前执行std::getline()
调用(并且之后std::cin >> age
调用)以便删除换行符。
不同之处在于ignore()
仅丢弃 1 个字符(或给定参数时丢弃 N 个字符),并且std::ws
继续忽略空格,直到找到非空格字符。因此,如果您不知道下一个标记之前有多少空格,您应该考虑使用它。
匹配操作
当您遇到这样的问题时,通常是因为您将格式化输入操作与未格式化输入操作组合在一起。格式化输入操作是指您获取输入并将其格式化为某种类型。就是这样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);
or
// Formatted I/O
int age;
std::string firstName, lastName;
std::cin >> age >> firstName >> lastName;
如果您选择使用未格式化的操作将所有内容作为字符串读取,您可以随后将它们转换为适当的类型。