我一直不清楚getline()和get()的区别,最近看了C++ Primer,终于增加了一些了解今天先写写getline()这个函数。
用一个函数来观察getline()的使用特点。
函数如下:
void getlineDemo1()
{
cout<<"getlineDemo1:缓冲区的作用: 暂时存储从键盘输入的数字,以便随后提供给cin的函数来读取"<<endl;
char wordArray1[5];
char wordArray2[5];
cout<<"plz input the value of word to wordArray1 and wordArray2"<<endl;
cin.getline(wordArray1,4);
cout<<wordArray1<<endl;
cin.getline(wordArray2,4);
cout<<wordArray2<<endl;
return;
}
运行结果:
getlineDemo1:缓冲区的作用: 暂时存储从键盘输入的数字,以便随后提供给cin的函数来读
取
plz input the value of word to wordArray1 and wordArray2
【输入】a[空格]b[回车]
【输出】a[空格]b
【输入】a[空格]bc
【输出】a[空格]b
Press any key to continue
说明:
1验证了getline()可以接受空格,但是不接收回车,回车是默认的分界符。并且不把分节符存入缓冲区。这点和get()不一样,在get()中,默认的分界符是会存入缓冲区供下一次读取的。
2验证了getline(wordArray2,5)中,实际上能够读入到wordArray中的字符个数为4-1=3。因为字符串数组wordArray末尾需要放入一个终结符NULL。
3第二次输入时,输入的数据为“a[空格]bc”这已经超过了wordArray的最大容量,此时cin会出现错误,表现在自身状态的改变。(这个状态叫做条件状态,其实是四个常量值,分别为bad, fail, eof和good。)
现在修改函数如下:
void getlineDemo1()
{ cout<<"getlineDemo1:缓冲区的作用: 暂时存储从键盘输入的数字,以便随后提供给cin的函数来读取"<<endl;
char wordArray1[10];
char wordArray2[10];
char wordArray3[10];
cout<<"输入wordArray1和wordArray2的值,以回车作为分隔"<<endl;
cin.getline(wordArray1,5);
cout<<wordArray1<<endl;
cin.getline(wordArray2,5);
cout<<"观察状态cin.good()="<<cin.good()<<endl;
cout<<"观察状态cin.bad() ="<<cin.bad()<<endl;
cout<<"观察状态cin.fail()="<<cin.fail()<<endl;
cout<<wordArray2<<endl;
cin.getline(wordArray3,5);
cout<<"现在还能继续输入吗?输入结果是"<<wordArray3<<endl;
return;
}
运行结果:
getlineDemo1:缓冲区的作用: 暂时存储从键盘输入的数字,以便随后提供给cin的函数来读
取
输入wordArray1和wordArray2的值,以回车作为分隔
【输入】a[空格]b
【输出】a[空格]b
【输入】abcdef
【输出】观察状态cin.good()=0
【输出】观察状态cin.bad() =0
【输出】观察状态cin.fail()=1
【输出】abcd
【输出】现在还能继续输入吗?
Press any key to continue
说明:
1当输入的字符串超长时,fail()函数将返回为true。而bad()依然为false。即输入超长只是使得流的状态犯了fail这样的小错误,还没有到达bad这样的顶级错误。
2” 【输出】现在还能继续输入吗?这个结果说明,实际上wordArray3并没有从接收到任何字符串。这其实是因为cin出了错误。
3 fail可以人为改正么?可以。
现在修改函数如下,把上面程序中末尾处的
“cout<<wordArray2<<endl;
cin.getline(wordArray3,5);”
改变为
“cout<<wordArray2<<endl;
cin.clear();
cin.getline(wordArray3,5);”
运行结果:
getlineDemo1:缓冲区的作用: 暂时存储从键盘输入的数字,以便随后提供给cin的函数来读
取
输入wordArray1和wordArray2的值,以回车作为分隔
【输入】a[空格]b
【输出】a[空格]b
【输入】abcdef
【输出】观察状态cin.good()=0
【输出】观察状态cin.bad() =0
【输出】观察状态cin.fail()=1
【输出】abcd
【输出】现在还能继续输入吗?输入结果是efg
Press any key to continue
说明:
1用clear()重值错误状态之后,fail的值恢复到0。 流内部没有错误,此时,流先到缓冲区去找寻,发现了有上次输入遗留下来的数据”efg”,于是都不需要通过键盘接受数据了,先将缓冲区内的数据输出。
2 有没有可能既重置错误装填,又使得缓冲区的数据也被清理掉?用这个函数ignore()
MSDN中解释如下:
istream& ignore( int nCount = 1, int delim = EOF );
nCount : The maximum number of characters to extract.
Delim: The delimiter character (defaults to EOF).
这说明ignore()默认情况下一次丢弃一个字符,知道遇到文件结束标志为止。
现在用程序来验证,把
“cout<<wordArray2<<endl;
cin.ignore();“
修改为
“cout<<wordArray2<<endl;
cin.clear();
cin.ignore();“
输入和上面程序的输入保持一致,那么输出则变成了下面的样子:
运行结果:
getlineDemo1:缓冲区的作用: 暂时存储从键盘输入的数字,以便随后提供给cin的函数来读
取
输入wordArray1和wordArray2的值,以回车作为分隔
【输入】a[空格]b
【输出】a[空格]b
【输入】abcdef
【输出】观察状态cin.good()=0
【输出】观察状态cin.bad() =0
【输出】观察状态cin.fail()=1
【输出】abcd
【输出】现在还能继续输入吗?输入结果是fg
Press any key to continue
说明:
1在上一个程序中,最后一个输出是efg,现在由于ignore()丢弃了一个字符,输出编程了fg了。
2如何让丢弃的字符尽可能多,多大让每一次输入完之后都清空缓冲区,防止影响下一次的输入?
这么写:cin.ignore(1024, '/n')// 让前面1024个字符都被清除掉。