string中getline,cin的方法getline(),get总结
一、string中的getline不是string的成员函数,属于全局函数,使用需要include<string>,有两个重载版本:
函数原型参见:http://www.cplusplus.com/reference/istream/istream/getline/
标准信息来自《c++primer》和《c++ primer plus》,另http://blog.csdn.net/vanwaals/article/details/5753556
http://blog.csdn.net/mylovepan/article/details/7940719
istream& getline (istream& is, string& str, char delim);
istream& getline (istream& is, string& str);
这两个getline读取cin流里的字符串到str中,直到遇到下列情况结束,并返回:
(a)、遇到文件结束符,如windows下模拟的ctrl+z,或无效输入
(b)、遇到换行符,即Enter,将换行符留在缓冲区中,留给下一个输入,并不存入str中,所以输出str,要自己添加endl来换行
(c)、遇到设备故障
如果第一个字符为换行符,getline也将结束,则str被置为空串。getline函数返回istream引用的对象,和cin一样也可以用作condition(条件,即有真假的表达式)。
如果输入的字符串过长呢,会大于str的存储空间吗?不会,str自动根据输入来调整大小。如何结束while(getline(cin,str))循环呢?可以使用ctrl+z
1 #include<iostream> 2 #include<string> 3 using namespace std; 4 int main() 5 { 6 string line; 7 while(getline(cin,line)) 8 cout<<line<<"$"; 9 }
输入了三个字符串,每个用Enter结束输入,且输出没有换行,getline()不会忽略space、tab,遇到Enter就结束,那么换行符是否留在缓冲区呢?如果是,下次getline就会遇到该换行符,
导致结束。由于没有输入ctrl+z,循环条件一直为真,所以提示继续输入
gteline的第三个参数为分界符,用户可以自定义,任何有效的字符都可以,如#,默认的为Enter。
int main() { string s; while(getline(cin,s,'#')) cout<<s<<"$"; }
二、cin.getline,两个重载版本:
istream& getline(char* s, streamsize n);
istream& getline(char* s, streamsize n, char delim);
第一个参数为字符指针,第二个控制输入的最大字符(等于n-1,最后一个位置存'\0',以便把输入存为字符串),如果输入的字符串过长,会导致cin流状态无效
不能再输入,使用cin.clear()函数可以重设cin的状态为有效。两个函数读取分界符或最大数目的字符为止。注意:将cin.getline()将分界符或者换行符丢弃,即缓冲区不会
有分界符用于下一个输入。但是如果输入的字符串过长,余下的字符会留在缓冲区。
int main() { char c[4]; cin.getline(c, 4); cout << c; }
输入超过了4个字符,存入c的只有三个字符
1 int main() 2 { 3 char c[4]; 4 cin.getline(c, 4); 5 cout << c; 6 if (!cin) cout << "cin error" << endl; 7 cin.getline(c, 3); 8 }
cin状态已经无效,!cin为测试条件。所以下一条输入语句不执行,不再有输入提示。
int main() { char c[4]; cin.getline(c, 4); cout << c; if (!cin) cout << "cin error" << endl; cin.clear(); cin.sync(); cin.getline(c, 3); cout << c << endl; }
h
使用cin.clear()与cin.sync()(清空缓冲区),才可以继续输入“123”,由于n=3,只能读取2个字符。
三、cin.get():
istream& get(char *,int,char); istream& get(char*,int);
用于单字符输入的 istream& get(char&);int get();
这是个函数都是istream类的方法,需要对象cin才能调用,与string中的getline()不同。
cin.get()与cin.getline()的不同之处为:遇到换行符或分界符,get会留该字符在缓冲区,所以cin.get()的连续两次调用,后一次会读取缓冲区的字符,不会再请求输入。
char c[6]; char a[6]; cin.get(c,5); cin.get(a,4);
这样cin.get()无法跨行输入,解决办法是使用get的变体,下面介绍两个新get函数:
istream &get(char&);int get();
第二个函数与c的库函数getchar()一样,可以替换后者;它的使用代码为:
char ch; ch=cin.get(); while(ch !='\n') { cout<<ch; ch=cin.get(); }
这两个get都用于单字符的输入,且space,tab,Enter都能输入。通过在cin.get(c,5)与cin.get(a,4)间插入cin.get()这条语句,读取了缓冲区的换行符,cin.get(a,4)
才能继续读取输入。
istream &get(char&)的使用方式为 char ch; cin.get(ch);由于返回的是istream对象,所以cinget(ch).get(ch2)>>c3运行正常。也可以用cin.get(ch)为循环的测试条件。
四、cin的特点
cin用于输入int ,char ,string 等基本类型,不能输入一行字符到str中。cin遇到space,tab,Enter会自动忽略,从缓冲区中丢弃,但是后续的输入会留在缓冲区,下一次的输入会直接从缓冲区读取数据。
int sum=0; int n; while(cin>>n,n!=20) { sum+=n; } cout<<sum<<endl;
换行输入space后又输入6,3,4,但是循环无法结束,此时输入20可以结束。
1+2+3+4+5+6+3+4=28。注意:while(cin>>a,a!=20)的测试条件是逗号表达式,值为逗号右边的子表达式,而不是cin>>a的返回值cin。
注意:如果int a;cin>>a;输入的不是整数,cin>>a是无效输入,不能再输入。