C++中的cin 深入理解

参考网址:
C++中 cin的深入理解
C++中cin的详细用法
C++:cin、cin.getline()、getline()的用法

一、cin简介

C++中的cin是一个 istream对象,从标准输入中读取数据,在iostream头文件中定义。

流对象不能拷贝或赋值。此外,读写一个IO对象都会改变其状态,因此传递和返回的引用都不能是const的,否则无法读写。

条件状态:
IO流有四种条件状态,分别用位来控制。
cin.badbit : 001 1 表示系统级错误,一旦被置位,流就无法再使用了
cin.eofbit : 010 2 表示流已经读完,到达尾部了
cin.failbit: 100 4 可恢复错误,如期望读取数值却读出一个字符等错误,或者已经到达流的尾部
cin.goodbit: 000 0 可用状态

当一个流遇到数据类型不一致的错误而不可用时,我们可以使其恢复为有效状态(置换eof和fail位)

也可通过调用成员函数查看流的状态,如:cin.eof() cin.fail() cin.bad() cin.good() //相应状态为真则返回true,反则为false

二、cin从缓冲区读取数据

cin从缓冲区读取数据,有多种方式,如操作符 >> 、函数getline()、get()等

1. >>

  • 根据后面的变量的类型读取数据
  • 读取时结束条件:enter, space, tab
  • 对结束符的处理:丢掉
#include <iostream>  
using namespace std;  
int main()  
{  
   char str1[10], str2[10];  
   cin>>str1;  
   cin>>str2;  
   cout<<str1<<endl;  
   cout<<str2<<endl;  
   return 0;  
}  
  • 当遇到类型不一致时,流处于不可用状态,若需继续使用这个流,需恢复流的有效状态。
cin.clear( cin.rdstate() & ~cin.failbit & ~cin.badbit );   //cin.rdstate()表示流当前的状态

2. get

  • 输入结束条件:换行符
  • 对结束符处理:不丢掉
#include <iostream>  
using namespace std;  
int main()  
{  
  char c1, c2;  
   cin.get(c1);  
   cin.get(c2);  
    cout<<c1<<" "<<c2<<endl; // 打印两个字符  
    cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值(用cout打印char型的ASCII值必须要强制转换)  
    return 0;  
}  

运行结果:
输入:a b
结果:c1被赋值为a, c2被赋值为空格。
这里写图片描述
分析:即get函数只会从缓冲区中取字符,而不会过滤掉任何空格换行符等。(可自己运行只输入a和换行符的情况)

#include <iostream>  

int main()  
{  
    int c1, c2;  
    c1=cin.get();  
    c2=cin.get();  
    cout<<c1<<" "<<c2<<endl; // 打印两个字符  
    cout<<(int)c1<<" "<<(int)c2<<endl; // 打印这两个字符的ASCII值  

    cin >> c1;  
    cin >> c2;  
    cout<<c1<<" "<<c2<<endl; // 打印两个字符  
    cout<<(int)c1<<" "<<(int)c2<<endl;  
    return 0;  
}  

运行结果:
输入:123,换行,结果打印:两行49,50。然后输入4,换行,结果打印:两行3 4。
结果:
这里写图片描述
分析:
cin.get()只是读取字符,即使输入数字,也是char型,再转换为int型。第一次c1,c2被赋值为’1’和’2’,此时缓冲区还有一个3和换行符,cin流仍然有效,再次调用cin流,给c1赋值为缓冲区的3,过滤掉换行符,再次调用cin时,缓冲区已经没有字符了,则从键盘读取,提示用户输入,输入4赋值给c2。此时的c1和c2直接是int型的。

3.getline()

getline读取一行,以换行符结束,丢掉换行符。
还可指定读取多少个字符到数组,读取完后剩余的字符放在流中,流被置为无效状态,可以通过置换使他们变有效,然后继续读取,见例子。

#include <iostream>  
int main()  
{  
    char str[10];  
    cin.getline(str,5);  
    cout << str << endl;  
    cout << "read state: " << cin.rdstate() << endl;  
    cin.clear(cin.rdstate() & ~cin.failbit);  
    cout << "read state: " << cin.rdstate() << endl;  
    cin.getline(str,5);  
    cout << str << endl;  
    return 0;  
}  

运行结果:
输入:abcdefghijklmnop
结果:
这里写图片描述

4.cin之后使用getline会出现空行,调用cin.ignore()即可

#include <iostream>  
#include <string>  

using namespace std;  
int main()  
{  
    int n;  
    cin >> n;  
    cin.ignore(); //如果注释掉  
    string c;  
    getline(cin, c);  
    cout << c << endl;  
    return 0;  
}  

运行结果:
如果注释掉cin.ignore(),输入2\enter,输出空行。
这里写图片描述
不注释,输入2\enterA,输出A。
这里写图片描述
因为cin有时会以\n作为结束标志,但它还在缓存区中,而getline以\n为结束标志,会读取上一次输入得到的\n,得到一个空行。
cin.ignore(1000, ‘\n’)的含义是把缓冲区内从当前字符开始直到’\n’之前字符(如果有1000个的话)忽略掉,实际上你这里假设一行不会超过1000个字符,所以含义是忽略一行。

5. 清空输入流缓冲区中错误字符

// cingolf.cpp -- non-numeric input skipped
#include <iostream>
const int Max = 5;
int main()
{
    using namespace std;
// get data
    int golf[Max];
    cout << "Please enter your golf scores.\n";
    cout << "You must enter " << Max << " rounds.\n";
    int i;
    for (i = 0; i < Max; i++)
    {
        cout << "round #" << i+1 << ": ";
        while (!(cin >> golf[i])) {
            cin.clear();     // reset input
            while (cin.get() != '\n')
                continue;    // get rid of bad input
            cout << "Please enter a number: ";
        }
    }
// calculate average
    double total = 0.0;
    for (i = 0; i < Max; i++)
        total += golf[i];
// report results
    cout << total / Max << " = average score "
            << Max << " rounds\n";
    // cin.get();
    // cin.get();
    return 0; 
}

运行结果:
这里写图片描述

6. getline()

用法:接收一个字符串,可以接收空格并输出,需包含#include <string>

#include<iostream>
#include<string>
using namespace std;
main ()
{
    string str;
    getline(cin,str);
    cout<<str<<endl;
}

输入:jkljkljkl
输出:jkljkljkl

输入:jkl jfksldfj jklsjfl
输出:jkl jfksldfj jklsjfl

注意:cin.getline()属于istream流,而getline()属于string流,是不一样的两个函数

  • 10
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值