为什么在 "cin" 之后使用 "getline" 时需要 cin.ignore(),而在多次使用 "cin" 时不需要?
Why is cin.ignore() necessary when using "getline" after "cin", but is not required when using "cin" multiple times?
据我所知,在 cin
之后使用 getline()
时,我们需要先刷新缓冲区中的换行符,然后再调用 getline()
,我们通过调用 cin.ignore()
.
std::string name, address;
std::cin >> name;
std::cin.ignore(); //flush newline character
getline(std::cin,address);
但是当使用多个cin
时,我们不需要刷新换行符。
std::string firstname, lastname;
std::cin >> firstname;
std::cout << firstname << std::endl;
//no need to flush newline character
std::cin >> lastname;
std::cout << lastname << std::endl;
这是为什么?为什么第一种情况需要cin.ignore()
,而最后一种情况不需要?
因为 getline()
从给定的 std::istream
读取 直到下一个换行符 字符,而 std::istream::operator>>()
跳过 任意白色spaces(空格、制表符和换行符)。
因此,当您读取整数或浮点数时,所有尾随的白色space都会留在输入流中。当您从控制台或终端读取时,您键入数据并按 Enter,后者留在流中,如果您不清除它,将被 getline()
捕获。
您不必清除它,因为下次您阅读 std::string
时,std::istream::operator>>()
会为您跳过白色space。
考虑这个代码段;
std::string a, b;
std::cin >> a;
std::getline(std::cin, b);
和这个输入:
Stack Overflow<Enter>
Where developers learn.<Enter>
第一个 cin
语句将读取单词 Stack
,留下 space 和 Overflow<Enter>
。然后它会被getline
读取,所以
assert(b == " Overflow");
如果你在调用getline()
之前插入一个std::cin.ignore()
,它会变成
assert(b == "Where developers learn.");
signed main(){
/*
* input is of next two lines
* Stack Overflow<Enter>
* Where developers learn.<Enter>
* for more about cin.ignore visit http://www.cplusplus.com/reference/istream/istream/ignore/
*/
string name, address;
cin>>name;
//cin.ignore();
//cin.ignore(256,'\n');
getline(cin,address);
cout << address << endl;
assert(address == " Overflow"); // breaks if using cin.ignore() or cin.ignore(256,'\n')
assert(address == "Overflow"); // breaks if using cin.ignore(256,'\n') OR not using any
assert(address == "Where developers learn."); // breaks if using cin.ignore() or not using ignore
}
输入
Stack Overflow
Where developers learn.
据我所知,在 cin
之后使用 getline()
时,我们需要先刷新缓冲区中的换行符,然后再调用 getline()
,我们通过调用 cin.ignore()
.
std::string name, address;
std::cin >> name;
std::cin.ignore(); //flush newline character
getline(std::cin,address);
但是当使用多个cin
时,我们不需要刷新换行符。
std::string firstname, lastname;
std::cin >> firstname;
std::cout << firstname << std::endl;
//no need to flush newline character
std::cin >> lastname;
std::cout << lastname << std::endl;
这是为什么?为什么第一种情况需要cin.ignore()
,而最后一种情况不需要?
因为 getline()
从给定的 std::istream
读取 直到下一个换行符 字符,而 std::istream::operator>>()
跳过 任意白色spaces(空格、制表符和换行符)。
因此,当您读取整数或浮点数时,所有尾随的白色space都会留在输入流中。当您从控制台或终端读取时,您键入数据并按 Enter,后者留在流中,如果您不清除它,将被 getline()
捕获。
您不必清除它,因为下次您阅读 std::string
时,std::istream::operator>>()
会为您跳过白色space。
考虑这个代码段;
std::string a, b;
std::cin >> a;
std::getline(std::cin, b);
和这个输入:
Stack Overflow<Enter>
Where developers learn.<Enter>
第一个 cin
语句将读取单词 Stack
,留下 space 和 Overflow<Enter>
。然后它会被getline
读取,所以
assert(b == " Overflow");
如果你在调用getline()
之前插入一个std::cin.ignore()
,它会变成
assert(b == "Where developers learn.");
signed main(){
/*
* input is of next two lines
* Stack Overflow<Enter>
* Where developers learn.<Enter>
* for more about cin.ignore visit http://www.cplusplus.com/reference/istream/istream/ignore/
*/
string name, address;
cin>>name;
//cin.ignore();
//cin.ignore(256,'\n');
getline(cin,address);
cout << address << endl;
assert(address == " Overflow"); // breaks if using cin.ignore() or cin.ignore(256,'\n')
assert(address == "Overflow"); // breaks if using cin.ignore(256,'\n') OR not using any
assert(address == "Where developers learn."); // breaks if using cin.ignore() or not using ignore
}
输入
Stack Overflow
Where developers learn.