C++ cin.get()和cin.getline()方法详解及区别

来源:互联网 发布:网络宣传计划书范文 编辑:程序博客网 时间:2024/06/16 00:47

一、cin.get(...)

该方法有四种常用的形式:

int get();                                              //#1istream& get(char& c);                                  //#2istream& get(char* s, streamsize n);                    //#3istream& get(char* s, streamsize n, char delim);        //#4
首先讲解第一种形式:int get();

该方法从输入流中提取一个字符然后以将其以int类型进行返回,通常是下面这样使用的:

char ch;ch = cin.get();
此时ch为cin.get()从输入流中提取的一个字符,因为返回的是int类型,不是istream类型,所以不能拼接使用,下面介绍的一种形式将可以用于拼接。

第二种形式:istream& get(char& c);

该方法也是从输入流中提取一个字符,但不是将字符进行返回,而是将提取的字符赋给参数中引用c中,下面是使用方法:

char ch;cin.get(ch);           //将提取的字符赋给参数ch 因为方法形参是个字符引用,所以可以在函数中修改ch值
另外该形式的get()方法可以进行拼接,什么意思呢?看下面使用方法:

char ch1;char ch2;cin.get(ch1).get(ch2);      //拼接使用该方法
因为该形式的gett()方法返回一个istream对象引用,所以当cin.get(ch1)执行完毕后将提取的第一个字符赋给ch1的引用,然后返回一个istream对象引用,这里为*this,因为这里get()是istream对象调用的方法,所以当第一个get()执行完毕后返回*this紧接着执行第二个get(),形式类似于:(*this).get(ch2)或cin.get(ch2)  所以如果需要分别从输入流中提取俩字符到俩字符变量中时,可以用该拼接方法。

另外如果是将istream对象放到接受bool值参数的地方时,istream对象将转换成bool类型,看下面方法:

char ch;while(cin.get(ch)){       //方式1...}

char ch;cin.get(ch);while(cin){               //方式2...cin.get(ch);}
这俩种方法都是将istream类对象 如cin 放到接受bool值的地方,都将自动转换成bool值类型,如cin.get()因错误被设置流状态时,istream类对象将为false,如果一切顺利的话,istream对象将为true将继续执行while块。

下面再来介绍第三种形式get()方法:istream& get (char* s, streamsize n);

该种方法接受俩参数,第一个参数接受一个字符指针,指向希望从流中提取的字符串的存放位置,第二个参数接收一个需要从流中提取的字符个数,实际上该get()只会从流中提取n-1个字符,然后最后一个字符默认为'\0'空字符。例如:

const int arrSize = 5;char Str[arrSize];cin.get(Str,arrSize);

上面例子创建一个Str字符数组,大小为arrSize,这里为5 然后调用cin.get()方法,将存放位置指向该数组(Str),接受字符数设置为arrSize个,上面说过,实际上get()只会提取arrSize-1个字符,假设输入abcdef,这里get()只从流中提取arrSize-1个字符也就是前4个,然后Str各个元素为:{'a','b','c','d','\0'}也就是C风格字符串“abcd”。当输入超过4个字符的时候,get()提取后多出来的字符将留在输入流中,而不会清空,包括按下回车符时输入的'\n'换行符。下一次调用cin进行输入的时候将首先自动提取这几个残留的字符,而不会等到用户自己输入。

所以如果输入过多的字符,要清空残留的字符时可以使用下面方法:(当然在没有错误输入导致状态位被设置时该方法才有效 如果被设置状态位而关闭输入 下面方法将无效,因为无法读取字符,而直接返回EOF,可以通过cin.clear()方法清除状态位以便继续读取字符)

while(cin.get() != '\n'){continue;}
另外需要注意的是该重载版本的get()方法不接收“无值输入”也就是说当执行cin.get(Str,arrSize);该行代码时,用户没有输入任何其他字符直接按下回车(换行符  该重载版本的默认分界符)接受指定分界符的get()重载版本将在下面讲解。由于没有从输入流中提取到有效字符到Str中,所以自动将Str[0]设置为'\0'空字符,然后设置ios_base::fail错误标志位,此时将关闭输入,要想后面再次输入的话需要使用cin.clear()或其他等价方法进行清除错误标志位以便继续读取输入。

第四种形式的get()方法:istream& get(char* s, streamsize n, char delim);

该重载版本get()方法接受三个参数,第一个参数是指向从流中提取的字符串存放的位置,第二个参数接收一个需要从流中提取的字符个数,这俩个参数跟上面一个版本的get()是一样的,而第三个参数接受一个字符,并将其作为指定的分界符,前一个版本的get() 方法istream& get (char* s, streamsize n);实际默认以'\n'换行符作为分界符的,那么分界符有什么用呢?比如第三种形式的get()方法从输入流中读取字符直到读取了第二个参数所指定的数目n-1个或者遇到分界符为止(这里是换行符作为分界符),还是以下面代码作为例子:

const int arrSize = 5;char Str[arrSize];cin.get(Str,arrSize);
当我输入ab并按下回车时,由于原本是提取arrSize-1也就是4个字符的,但是读取完第二个字符后进行读取第三个字符遇到了换行符(回车相当于键入换行符)于是停止继续读取,然后从流中提取的ab俩字符赋给Str数组并在尾部加上'\0'空字符,此时流中还是残留着换行符,注意:该重载版本的get()不读取分界符也不删除流中的分界符!总之后面俩种形式的重载get()版本,当从流中读取到指定数目的字符时或提前遇到换行符时,将停止继续读取。而第四种形式的get()重载版本与第三种类似,只是可以在第三参数中指定分界符而已,行为都是差不多的。

二、cin.getline(...)

该方法有两种形式的版本:

istream& getline (char* s, streamsize n );                     //#1istream& getline (char* s, streamsize n, char delim );         //#2
这俩种重载版本与上面讲到的cin.get()第3和第4版本的使用方法是一样的:

istream& getline (char* s, streamsize n ) 跟 istream& get(char* s, streamsize n)类似istream& getline (char* s, streamsize n, char delim ) 跟 istream& get(char* s, streamsize n, char delim)类似
所以这里就不讲解getline()的使用方法了,这里只简单总结下他们的区别:

get()对应的getline()版本区别是 get()不接收“空值输入”如果是空值输入将设置流错误状态位,并关闭输入,并且流中残留分界符(这里为换行符),当下一次能正常输入时,将首先读取该换行符作为字符,除非某些方法也自动丢弃该换行符。而getline()接受"空值输入"因为getline()读取分界符并将其丢弃,因为分界符也是一个值,所以不会导致设置错误状态位,并且流中将不存在残留的分界符(这里为换行符)因为已经读取并丢弃。另外getline()版本当遇到输入过多的字符时(当getline()读取了n-1个字符后 再检测留在流中的第一个字符是不是分界符 如果是则读取并丢弃 否则将设置错误标志位并关闭输入)。

以上就是我对cin.get()和cin.getline()各个重载版本的理解,如有误,还请各位指出来,在此感谢大家。

阅读全文
0 0
原创粉丝点击