关于cin的get()和getline()成员函数

cin是使用空白(空格,制表符,换行符)来确定字符串的结束位置这意味着cin在获取字符数组时只读取一个单词。读取该单词后cin自动在其结尾增加空字符。
这有时候很方便,有时候有使我们烦恼:如果我要输入一句话来存入字符串中呢?

要将整条短语而不是一个单词作为字符串输入,需要采用另一种字符串读取方法。
具体地说,需要采用面向行而不是面向单词的方法。

istream的类cin提供了一些面向行的类成员函数:getline() and get()
这两个函数都读取一行输入,直到遇到换行符为止。
不同的是getline()随后将丢弃换行符,而get()将换行符保留在输入序列中。

下面先说说getline():

geiline的使用方法是cin.getline(char*, int)。
该函数有两个参数,第一个是你要储存的目标,第二个是最多读取多少位字符。如,若该参数为29,则最多读取28个字符。余下的空间是留给空字符的。
getline成员函数在读取指定字符数或者遇到换行符时停止读取。
注意,可以认为getline()读取换行符,但随后将换行符丢弃,换成空字符。

关于get():

get成员函数有多重变体,其中有一种与getline相似,他们接受的参数个数相同,参数的解释也相同,并且都读取到行尾。
值得注意的是,get函数并不读取并丢弃换行符,而是将其留在输入序列中。这种特点如果不留意的话,会造成一些难以预料的麻烦。
下面举个栗子,当我们连续两次使用get():

cin.get(name, size);
cin.get(hobby, size);

第一次调用get()时,将换行符留在输入队列中,因此第二次调用时看到的第一个字符便是换行符,因此第二个get函数会认为已经到达行尾,便不再读取以下内容。
这个时候我们需要借助get函数的另一种变体,即不带任何参数的get函数:cin.get(),它可以读取下一个字符,即使是换行符,因此可以用它来处理换行符。
它的调用形式可以是以下两种:

//第一种:
cin.get(name, size);
cin.get();
cin.get(hobby, size);
cin.get();
//第二种:
cin.get(name, size).get();//之所以可以这样做,是因为cin.get(name, size)返回一个cin对象,
              //这个对象随后被用来访问get成员函数。
cin.get(hobby, size).get();

More:在使用cin之后使用getline的情况,如:

int year;
char name[20];
cin >> year;
cin.getline(name, 20);

这种情况下name中储存的不是我们输入进去的字符串,而是空字符串。原因是cin在读取year之后将换行符留在了输入队列,getline一开始就遇到换行符。
而我们以前连续调用cin不会产生读取空字符串的情况,是因为cin会自动忽略掉开头的换行符。

另外再做一下说明:
getline(char*, int)成员函数和get(char*, int)成员函数不适合于C++的string类。
或者这么说,适用于string类的getline函数并不是istream的成员函数,而是其友元函数,因此如果要读取一行字符串到string对象中,需要使用下面的格式:

getline(cin, str);

而get函数不适合于string类对象。
为什么string类的对象搞特殊呢?这是历史原因啦。

关于cin.get()函数的补充:

get()函数还有两种变体

一种是接受一个char类型作为参数:
cin.get(ch);

该函数返回一个cin对象。
由于cin在需要的情况下可以转为bool值,所以可以用cin.get(ch)函数来判断输入是否到达结尾:

cin.get(ch);
while (cin) {
     ……
     cout << ch;
     cin.get(ch);

}

//或者采用更简洁的表示:
while (cin.get(ch)) {
     cout << ch;
}

P.S.这里的“输入到达结尾”是指从键盘模拟的EOF,Windows下是Ctrl + z + Enter

另一种是
ch = cin.get();

该函数不接受任何参数,它的作用是读取下一个字符并赋值给ch。
当然这个表达式的值是赋值运算符左边的值,即ch;
所以这个函数也可以用来判断输入是否到达结尾:

while (ch != EOF) {
    cout << ch;
    ch = cin.get();
}
//或者采用更简洁的表示:
while ((ch = cin.get()) != EOF) {   //这个表达式的值是赋值运算符左边的值,即ch;
    cout << ch;
}

在希望逐字节地读取文本文件或文本输入时,可以使用这两个函数。
为什么不是cin >> ? 因为cin将自动地忽略空格,换行符,制表符,有时候,我们并不期待这种事情的发生。

                                      下面是这两个函数的区别:
属性cin.get(ch)ch = cin.get()
传递输入字符的方式赋给参数ch将函数返回值赋给ch
用于字符输入时函数的返回值istream对象(执行bool转换后为true)int类型的字符编码
到达EOF时函数的返回值istream对象(执行bool转换后为false)EOF

另外,cin.get(ch)还有一个好处就是它可以拼接起来,如:

cin.get(ch1).get(ch2);

最后,指出下列cin成员函数也可以判断输入是否到达结尾:

cin.fail()
cin.eof()
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值