cin与getline
初学C++的同学常常会遇到这样一个问题:如何从标准输入流中输入一个带有空格的句子?通过不断的Google或者翻书,往往会发现个``getline’’这个全局函数,它可以从标准输入输出流中拿到一行,并且输入参数是string类型:
istream& getline ( istream& is, string& str, char delim );
istream& getline ( istream& is, string& str );
不过一旦动手就会遇到一个新问题:cin >>和getline混用的时候会出错,比如:
01 ...
02 int var;
03 string name;
04 ...
05 cin >> var;
06 getline(cin, name);
07 ...运行之后,你会发现你只能输入一次,当你输入了``var''这个变量的值之后,``getline(cin, name)''这一行会被跳过,仿佛没有执行过一般,这是怎么回事?
这里我们需要了解流提取操作符``>>’’的一些特点,这个重载过的操作符的实现的功能顾名思义就是从输入缓冲中提取一个词,再将这个词转化为它后面的变量的类型,比如:
01 #include
02 #include
03 #include
04
05 using namespace std;
06
07 int main ( int argc, char *argv[] )
08 {
09 string str1;
10 streamsize size;
11 // if you use Visual Studio, next line is unnecessary, comment it.
12 ios::sync_with_stdio(false);
13
14 cout << "Input : ";
15 cin >> str1;
16
17 streambuf *pBuf = cin.rdbuf();
18 size = pBuf->in_avail();
19
20 cout << "Your input is : " << str1 << endl;
21 cout << "There is still " << size << " chars in the buffer." << endl;
22
23 return EXIT_SUCCESS;
24 } // ---------- end of function main ----------假如你在第15行的``cin >> str1''处输入了``Hello World!'',cin第一次只读入Hello,后面8个字符仍在输入缓冲中,所以第21行会输出``There is still 8 chars in the buffer.''。换句话说,``>>''读到下一个空白字符的前一个字符,不过它将空白字符留在输入缓冲中。
也就是因为这一点,getline''和
>>’’混用的时候会有小摩擦,考虑本文的第一个例子,当在cin >> var''中输入3然后回车之后,`3'作为数字被赋值给了
var’’,但是换行符被留在了输入缓冲中,``getline(cin, name);’’在读入换行符之后就认为已经读到了一整行:
Extracts characters from is and stores them into str until a delimitation character is found.
The delimiter character is delim for the first function version, and ‘\n’ (newline character) for the second. The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.
If the delimiter is found, it is extracted and discarded, i.e. it is not stored and the next input operation will begin after it.上面这一段是cplusplus上对getline函数的说明:http://www.cplusplus.com/reference/string/getline/,大意就是说``getline''在输入缓冲读入输入的时候是从第一个字符开始,并且再读入之后,将换行符从输入缓冲中删掉(这个才是好的行为啊)
由以上两点不难理解为什么跟在>>''之后的
getline’’会被跳掉,其实不是被跳掉,而是读了一个换行符`\n’就收工了……
那么怎么解决呢?
- 不要混用
cin''和
getline’’; - 在使用
cin''之后调用
cin.ignore(256, ‘\n’)’’,将输入缓冲中的换行符清空掉……