深入理解C++输入输出流

本文深入探讨了C++中的输入输出流,包括为何引入输入输出流,标准输入输出流的使用,如cout、cin、cerr,以及流状态、错误处理。接着讲解了基于文件的输入输出流和文件流的打开模式、定位操作。此外,还介绍了IO流缓冲和基于字符串的输入输出流,以及输出流的格式化操作。文章通过实例详细解释了如何为自定义类型支持输入输出流,以及如何处理流错误和状态。
摘要由CSDN通过智能技术生成

为什么引入输入输出流?

因为C++兼容C,所以C中的输入输出函数依然可以在C++中使用,但是很显然如果直接把C的那套输入输出搬到C++中肯定无法满足C++的需求,第一点也是最重要的一点那就是C中的输入输出有类型要求,只支持基本类型,很显然这是没办法满足C++的需求的,因此C++设计了易于使用的并且多种输入输出流接口统一的IO类库。并且还支持多种格式化操作。还可以自定义格式化操作。C++中总体来说有三种输入输出流,第一种就是标准的输入输出,第二种是文件的输入输出,第三种是基于字符串的输入输出流。C++引入IO流,将这三种输入输出流接口统一起来,使用>>读取数据的时候,不用去官是从何处读取数据,使用<<写数据的时候也不需要管是写到哪里去。

标准输入输出流的

最常用的就是标准输出cout,标准输入cin,以及标准错误输出cerr,这三个其实就是istream,ostream这两个类的全局实例。标准的输入和输出流也是大多数情况下我们使用的最多的一种输入输出流了,前面说过,对于IO流来说可以支持自定义类型,通过给自定义类型重载标准输入和输出流可以让自定义类型支持IO流,通常这也是很方便实现的。下面给出一个具体的例子:

自定义类型Date的实现:

class Date
{
  public:
    Date(int year,int month,int day)
         :m_day(day),m_month(month),m_year(year)
    {
    }
    ~Date()
    {
    }
    int getMonth()const {
        return m_month;
    }
    int getDay()const {
        return m_day;
    }
    int getYear()const {
        return m_year;
    }

  private:
    int m_day;
    int m_month;
    int m_year;
};

上面是一个自定义类型,如何让其支持输入和输出流?,需要对输出流进行重载,函数原型如下:

ostream& operator<<(ostream& os,const Date& d);

很显然这个函数不能是成员函数,因为第一个参数必须是输出流类ostream,为了让输出流支持链式表达式,所以函数返回ostream的引用,如果要输入的数据是Date类的私有成员,可以将这个函数设置为Date类的友元函数,本文没有这样做,因为Date类已经将数据通过public接口输入了。下面是具体实现.

ostream& operator<<(ostream& os,const Date& d) {
    char fillc = os.fill('0');
    //设置填充字符,当输出长度小于指定的长度的时候用于进行填充
    os<<setw(2) << d.getMonth() << '-' //setw用来设置输出长度
      <<setw(2) << d.getDay() << '-' 
      <<setw(4) << setfill(fillc) << d.getYear();
      //setfill还原回原来的填充字符
    return os; 
}

上面使用了一些操作流的函数,下文会展开来讨论。到此为此为自定义类型添加对输出流的支持就完成了。接下来看看如何重载标准输入流吧,实现如下:

istream& operator>>(istream& is,Date& d) {
    is >> d.m_month;
    char dash;
    is >> dash;
    if (dash != '-')
        is.setstate(ios::failbit);
        //设置流错误状态,这使得下面的所有操作都会被忽略
    is >> d.m_day;
    is >> dash;
    if (dash != '-')
        is.setstate(ios::failbit);
    is >> d.m_year;
    return is;
}

输入流也很简单,同样它也不能是成员函数,但是在这输入流必须是友元函数,因为这里直接对Date类的私有成员进行了操作,所以需要在Date类的开始处添加友元声明,如下:

class Date
{
  public:
    friend istream& operator>>(istream& is,Date& d);
    .....

到此为此输入流重载也很简单的实现了,在输入流中用到了setstate这个函数,这是用来设置流的状态的,C++中给流设置了许多状

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值