C++基础篇:08 文件

1 文件I/O流 

C++把对文件的读写操作都封装在以下类中:

        ① ofstream   对文件的写操作 继承了ostream类的功能

        ② ifstream    对文件的读操作 继承了istream类的功能

        ③ fstream     对文件的读写操作 继承了ofstream\ifstream类

2 C++对文本文件的读写

2.1 创建流对象,通过流对象打开文件

2.1.1 通过有参构造的方式创建流对象并直接打开文件

fstream( const char *filename, [openmode mode] );
ifstream( const char *filename, [openmode mode]);
ofstream( const char *filename, [openmode mode] );

2.1.2 通过open成员函数,打开文件

void open( const char *filename );
void open( const char *filename, openmode mode );

        mode:打开方式

            ios::app 添加输出

            ios::ate 当已打开时寻找到EOF

            ios::binary 以二进制模式打开文件

            ios::in 为读取打开文件

            ios::out 为写入打开文件

            ios::trunc 覆盖存在的文件

注意:

        ifstream类 默认只读方式打开文件,文件不存在会失败 r

        ofstream类 默认只写方式打开文件,文件存在则清空,不存在则创建   w

        fstream类 默认读写方式打开文件,文件不存在失败 r+

2.2 判断文件是否打开成功

2.2.1 使用 !流对象名 运算符重载的方式判断

if(!fin) // 失败

2.2.2 使用good\fail成员函数进行判断

good()   // 上一次文件操作没有错误,返回真
fail()   // 上一次文件操作有错误,返回真

2.3 读写文件

        C++是借助流操作进行文本文件的读写

        流对象 << 数据      //  写操作

        流对象 >> 数据      //  读操作

2.4 关闭文件、销毁流对象

void close();

        注意:只是关闭流对象当前打开的文件,流对象并没有销毁,还可以后续继续直接使用

        注意:在读写类对象时,由于绝大多数的成员变量都是private,因此无法直接在类外读写成员变量

        a、实现public属性的get\set成员函数来访问私有成员,虽然可以个性化访问,但比较麻烦

        b、由于ostream\istream分别是ofstream\ifstream的父类,因此如果重载这两个父类的 <<\>> 运算符,那么子类也会继承,所以重载输入输出运算符,既可以用于显示、输入对象,也可以具备通过运算符读写文件的效果,一举两得,更为便捷,但是格式相对较固定

3 C++的随机读写

        C++为文件IO提供了两套操作位置指针的函数,只是为了兼容支持两个位置指针的系统,但是UNIX/Linux/Windows系统底层都只有一个读写共享的位置指针,因此使用哪套都可以

ostream &seekp( off_type offset,ios::seekdir origin);

    功能:通过 基础位置+偏移值 设置写操作位置指针的位置

    offset:偏移值

    origin:基础位置

        ios::beg    文件开头

        ios::cur    当前位置

        ios::end    末尾位置

istream &seekg( off_type offset,ios::seekdir origin);

    功能:通过 基础位置+偏移值 设置读操作位置指针的位置

ostream &seekp( pos_type position );

    功能:通过 绝对位置 设置写操作位置指针的位置

    position:距离开头的字节数

 istream &seekg( pos_type position );

    功能:通过 绝对位置 设置读操作位置指针的位置

pos_type tellg();

    功能:获取读操作位置指针的位置

pos_type tellp();

    功能:获取写操作位置指针的位置

4 C++的读写二进制文件

① 创建流对象、打开文件

        注意:如果是Windows系统,mode打开方式需要增加 ios::binary 选项

② 判断文件是否打开成功

③ 读写操作

        通过成员函数 read\write 来进行二进制读写

ostream &write(const char *buffer,streamsize num);

        功能:以二进制写文件

        buffer:待写入数据的内存首地址

        num:要写入的字节数

istream &read( char *buffer, streamsize num );

        功能:以二进制方式读文件

        buffer:存储读取到的数据的内存首地址

        num:要读取的字节数

 注意:C++的write只有两种结果,要么num个字节全部写入成功,要么一个都每写入成功,因此通过good/fail判断上一次写入是否成功,所以不需要知道成功写入的个数[0\num]

streamsize gcount();

        功能:获取上一次二进制读文件成功读取到的字节数

bool eof();

        功能:判断文件流是否到达了文件末尾,如果是返回true

        否则返回false

while(true)
{
    fio.read();
    if(fio.eof()) break;
    //  执行读取成功后的相应操作
}

④ 关闭文件、销毁对象

注意:以二进制方式读写对象时,对象的成员不应该有指针类型(string),因为写入时只会把指针类型的对象存储的地址编号写入文件,而不会通过地址编号访问对应内存去写入,所以当后面重新读取文件时,读到的是之前写入的已经没有意义的地址编号,所以写入时需要深拷贝

        a、更换对象中的指针成员 例如string换成char[]

        b、通过深拷贝,把成员中指针指向的内存写入文件

5 类型信息获取

        C++中的typeid运算符可以获取数据的类型信息,需要添加头文件

  ① 运算符的结果是一个类对象

  ② 该对象中有一个name成员函数,可以返回数据的类型名

  ③ 该对象还重载了 == 运算符,可以判断两个数据类型是否相同(指针类型还会比较常属性)

  ④ 还可以区别某个父类指针或引用指向的是哪个子类对象,例如:Base* b = new Son1;  

  ⑤ 不可以重载

你可能感兴趣的:(C++,c++,数学建模,开发语言)