14.5.5 使用get函数和getline函数读取C风格字符串
istream类中重载了get函数和getline函数来一次性读取多个字符到C风格字符串中,大致有以下重载版本。
1.istream&istream:get(char*buffer,int size,char delim='\n');
该函数调用形式,用于读连续的字符到buffer中,停止条件有两个,即
第1个是达到最大字符数size-1;第2个是遇到分隔符delim(默认为换行符'\n'),只要两个条件有一个满足,读取便停止,在buffer最后加'\0'。注意分隔符不会写入字符串中,而是留在输入流中。
如以下示例代码14.20所示。
代码14.20 使用get函数读取C风格字符串GetAString1
<———————————-文件名:example1420.cpp———————————————-> 01 #include<iostream> 02 using namespace std; 03 const int Len=10;//定义常量Len,用以声明数组大小 04 int main() 05 { 06 char sz[Len]; 07 cin. get(sz,Len,'A');//get函数读取字符串 08 cout<<sz<<endl; 09 return 0; 10 }.
输出结果如下所示。
Congratulations(注:键盘输入) Congratul或 CONGRATULATION(注:键盘输入) CONGR
【代码解析】代码第7行使用get函数读取一串字符到字符数组sz中,输入停止的约束条件有两个,一是9个字符;二是出现字符'A',当输入“Congratulations”时,输出结果便为“Congratul”,达到了9个字符,但当输入大写形式“CONGRATULATION”时,因为出现了分隔符'A',所以,只读取了“CONGR”到sz中,分隔字符'A'不会被写出,留在了输入缓冲区中。
使用get函数读取字符串同样不会跳过任何形式的空格。
2.istream&istream:getline(char*buffer,int size,char delim='\n');
getline函数与前面介绍的get函数用法几乎一致,唯一的不同体现在对分隔符的处理,get函数将分隔符留在输入流中,而getline函数抽取并丢弃输入流中的分隔符(分隔符同样不会读取到字符串中),如以下示例代码14.21所示,用以体会两者的区别。
代码14.21 使用getline函数读取C风格字符串GetAString2
<———————————-文件名:example1421.cpp———————————————-> 01 #include<iostream> 02 using namespace std; 03 const int Len=10;//定义常量Len,用以声明数组大小 04 int main() 05 { 06 char sz1[Len],sz2[Len]; 07 cin. get(sz1,Len,'A'); 08 cin. get(sz2,Len); 09 cout<<sz1<<endl; 10 cout<<sz2<<endl; 11 cin. sync();//清空输入缓冲区 12 cin. getline(sz1,Len,'A'); 13 cin. getline(sz2,Len); 14 cout<<sz1<<endl; 15 cout<<sz2<<endl; 16 return 0; 17 }
输出结果如下所示。
CONGRATULATION(注:键盘输入) CONGR ATULATION CONGRATULATION(注:键盘输入) CONGR TULATION
【代码解析】代码中两者输入结果的不同体现在sz2的值上,get函数将分隔符'A'留在输入缓冲区中,因此,sz2以字符'A'开头,而代码第12行getline函数将分隔符'A'从输入缓冲区中提出,但不写入sz1中,而是抛弃掉,这样,sz2便以字符'T'开头。
还要特别说明的是换行符的处理,在程序中使用了语句“cin.sync();”来清空输入缓冲区,实际上语句“cin.get()”也可以胜任,共同的目的是将get函数读取sz2后残留在输入缓冲区中的换行符提出,否则,在使用getline读取字符到sz1中时,换行符会是sz1的第1个字符。
技巧理解换行符的处理十分重要,否则程序可能会出现一些意想不到的问题。