当前位置 博文首页 > wanggao的专栏:fstream读写文件注意问题

    wanggao的专栏:fstream读写文件注意问题

    作者:[db:作者] 时间:2021-09-09 09:52

    类ofstream, ifstream 和fstream是文件操作的三个类,分别从ostream, istream 和iostream 中派生而来。通常读、写文件分别使用 ifstream、ofstream。

    1、 打开文件

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

    filename 是一个字符串,代表要打开的文件名,mode 是以下标志符的一个组合:

    mode说明
    ios::in为输入(读)而打开文件
    ios::out为输出(写)而打开文件
    ios::ate初始位置:文件尾
    ios::app所有输出附加在文件末尾
    ios::trunc如果文件已存在,则先删除该文件
    ios::binary二进制方式

    三个类的默认读写方式为

    默认读写mode
    ofstreamios::out
    ifstreamios::in
    fstreamios::in

    注意:当函数被调用时没有声明方式参数的情况下,默认值才会被采用。如果函数被调用时声明了任何参数,默认值将被完全改写,而不会与调用参数组合。

    这些标识符可以被组合使用,中间以”或”操作符(|)间隔。例如,以二进制方式打开文件“file1.dat”,继续在写入一些内容,则为

    ofstream file;
    file.open ("file1.dat", ios::out | ios::app | ios::binary);

    2、文本文件

    可以直接用类似于std::cout 和 std::cin 通过重载的操作符>>和<<对fstream文件流进行读写。
    Eg1 : writing on a text file

    #include <fiostream.h>
    int main () 
    {
        ofstream examplefile ("example.txt");
        if (examplefile.is_open()) {
        examplefile << "This is a line.\n";
        examplefile << "This is another line.\n";
        examplefile.close();
        }
        return 0;
    }
    
    *** file example.txt ***
    This is a line.
    This is another line. 

    Eg2 : reading a text file

    #include <iostream.h>
    #include <fstream.h>
    #include <stdlib.h>
    int main () 
    {
        char buffer[256];
        ifstream examplefile ("example.txt");
        if (! examplefile.is_open())
        { 
            cout << "Error opening file"; exit (1); 
        }
        while (! examplefile.eof() ) 
        {
            examplefile.getline (buffer,100);
            cout << buffer << endl;
        }
        return 0;
    }
    
    ----- Console  -----
    This is a line. 
    This is another line. 

    文本文件读写相对较简单,也包含大量的函数,具体的可以查看下面网站
    http://www.cplusplus.com/reference/fstream/fstream/?kw=fstream。

    在给出一个读写的数据例子,首先存一些数据到文件“fatures.txt”,包含一个数据int num,再保存num个vector<double> featuresVec。之后再读取这个文件。

    Eg3: 存一些数据到文件“fatures.txt”

        vector<double> featuresVec;
        /*
         ....   featuresVec 的数据写入省略,假定17个值
        */
        ofstream fout("fatures.txt");
        int num = 160;
        fout << num << " ";
        for (int i = 0; i < num; i++) {
            for (double au : featuresVec){   
                fout << au <<" ";  //写featuresVec的每一个数据
            }
        }
        fout.close();

    Eg4: 读取文件“fatures.txt”中的数据

        ifstream fin("fatures.txt");
    
        int num;
        fin >> num;
    
        vector<vector<double>> ausVec;  //读取的num个vector<double>数据
    
        for (int i = 0; i < num; i++)
        {
            vector<double> tempVec;
    
            for (int j = 0; j < 17; j++) { //和写入时保持数据量一致
                double temp;
                fin2 >> temp;  //读取vector<double>中的每一个数据
                tempVec.push_back(temp);
            }
            ausVec.push_back(tempVec);
        }
        fin.close();

    3、二进制文件

    尽管使用<< 和>>,以及函数(如getline)来操作符输入和输出数据,是合法的,但是在在二进制文件中,这些操作没有什么实际意义。

    文件流包括两个为顺序读写数据特殊设计的成员函数:write 和 read。第一个函数 (write) 是ostream 的一个成员函数,都是被ofstream所继承。而read 是istream 的一个成员函数,被ifstream 所继承。类 fstream 的对象同时拥有这两个函数。它们的原型是:

    write ( char * buffer, streamsize size );
    read ( char * buffer, streamsize size );

    这里 buffer 是一块内存的地址,用来存储或读出数据。参数size 是一个整数值,表示要从缓存(buffer)中读出或写入的字符数。

    // reading binary file  
    #include <iostream>  
    #include <fstream.h>  
    
    const char * filename = "test.txt";  
    
    int main () 
    {  
        char * buffer;  
        long size;  
        ifstream in (filename, ios::in|ios::binary|ios::ate);  
        size = in.tellg();  
        in.seekg (0, ios::beg);  
        buffer = new char [size];  
        in.read (buffer, size);  
        in.close();  
    
        cout << "the complete file is in a buffer";  
    
        delete[] buffer;  
        return 0;  
    }  
    //运行结果:  
    The complete file is in a buffer  

    注意:若期望是二进制的文件读写,必须要指定读、写的模式有ios::binary,否则读取数据会出错。

    和前面文本读写类似,给出对应二进制的读写方法。
    Eg1: 写数据到二进制文件”fatures.dat”

        ofstream fou("fatures.dat", ios::binary);//必须指定binary
    
        int num = 160;
        fou.write((char*)&num, sizeof(int));  //写入num
    
        for (int i = 0; i < num; i++) {
    
            vector<double> featuresVec; 
            /*  
              ... featuresVec 的数据写入省略,假定17个值    
            */
            for (double au : featuresVec){
                //写入featuresVec的每一个double值,
                fou.write((char*)&au, sizeof(double)); 
            }
        }
        fou.close();

    Eg2: 、读取二进制文件”fatures.dat”中的数据

        ifstream fin("fatures.dat", ios::binary);  //必须指定binary
    
        int num;
        fin.read((char*)&num, sizeof(int));  //读取num
    
        vector<vector<double>> ausVec; //读取的num个vector<double>数据
    
        for (int i = 0; i < num; i++)
        {
            vector<double> tempVec;
    
            for (int j = 0; j < 17; j++) {//和写入时保持数据量一致
                double temp;
                fin.read((char*)&temp, sizeof(double));//读取vector<double>中的每一个数据
                tempVec.push_back(temp);
            }
            ausVec.push_back(tempVec);
        }
        fin.close();
    cs