使用read(),write(),seekg(),seekp()实现二进制方式文件随机存取

// binary.cpp -- binary file I/O
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>  //for exit()
using namespace std;

const char * file = "planets.dat";

struct planet
{
    char name[20];      //name of planet
    double population;  //its population
    double g;           //its acceleration of gravity
};
inline void eatline()
{
    while(cin.get() != '\n')
    {
        continue;
    }
}

int main()
{
    planet pl;
    cout << fixed << right;

    //show initial contents
    ifstream fin;

    fin.open(file, ios_base::in | ios_base::binary);    //binary file
    if(fin.is_open())
    {
        cout << "Here are the current contents of the " << file << " file:" << endl;
        while(fin.read((char* )&pl, sizeof pl))
        {
            cout << setw(20) << pl.name << ": "
                 << setprecision(0) << setw(12) << pl.population
                 << setprecision(2) << setw(6) << pl.g << endl;
        }
        fin.close();
    }

    //add new data
    ofstream fout;
    fout.open(file, ios_base::out | ios_base::app | ios_base::binary);
    if(!fout.is_open())
    {
        cerr << "Can't open " << file << " file for output:" << endl;
        exit(EXIT_FAILURE);
    }
    cout << "Enter planet name (enter a blank line to quit):" << endl;
    cin.get(pl.name, 20);
    while(pl.name[0] != '\0')
    {
        eatline();
        cout << "Enter planet's population: ";
        cin >> pl.population;
        cout << "Enter planet's acceleration of gravity: ";
        cin >> pl.g;
        eatline();
        fout.write((char *)&pl, sizeof pl);
        cout << "Enter planet name (enter a blank line to quit):" << endl;
        cin.get(pl.name, 20);
    }
    fout.close();

    //show revised file
    fin.clear();
    fin.open(file, ios_base::in | ios_base::binary);
    if(fin.is_open())
    {
        cout << "Here are the new contents of the " << file << " file:" << endl;
        while(fin.read((char *)&pl, sizeof pl))
        {
            cout << setw(20) << pl.name << ": "
                 << setprecision(0) << setw(12) << pl.population
                 << setprecision(2) << setw(6) << pl.g << endl;
        }
        fin.close();
    }
    cout << "Done." << endl;

    return 0;
}
//random.cpp -- random access to a binary file
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstdlib>
using namespace std;

const int LIM = 20;
const char * file = "planets.dat";

struct planet
{
    char name[LIM];     //name of planet
    double population;  //its population
    double g;           //its acceleration
};
inline void eatline()
{
    while(cin.get() != '\n')
    {
        continue;
    }
}

int main()
{
    planet pl;
    cout << fixed;

    //show initial contents
    fstream finout;     //read and write streams
    finout.open(file, ios_base::in | ios_base::out | ios_base::binary);

    int ct = 0;
    if(finout.is_open())
    {
        finout.seekg(0);    //go to beginning
        cout << "Here are the current contents of the " << file << " file:" << endl;
        while(finout.read((char *)&pl, sizeof pl))
        {
            cout << ct++ << ": " << setw(LIM) << pl.name << ": "
                 << setprecision(0) << setw(12) << pl.population
                 << setprecision(2) << setw(6) << pl.g << endl;
        }
        if(finout.eof())
        {
            finout.clear();     //clean eof flag
        }
        else
        {
            cerr << "Error in reading " << file << " file." << endl;
            exit(EXIT_FAILURE);
        }
    }
    else
    {
        cerr << file << " could not be opened -- bye." << endl;
        exit(EXIT_FAILURE);
    }

    //change a record
    cout << "Enter the record number you wish to change: ";
    long rec;
    cin >> rec;
    eatline();  //get rid of newline
    if(rec < 0 || rec >= ct)
    {
        cerr << "Invalid record number -- bye" << endl;
        exit(EXIT_FAILURE);
    }
    streampos place = rec * sizeof pl;  //convert to streampos type
    finout.seekg(place);    //random access
    if(finout.fail())
    {
        cerr << "Error on attempted seek" << endl;
        exit(EXIT_FAILURE);
    }

    finout.read((char *)&pl, sizeof pl);
    cout << "Your selection: " << endl;
    cout << rec << ": " << setw(LIM) << pl.name << ": "
         << setprecision(0) << setw(12) << pl.population
         << setprecision(2) << setw(6) << pl.g << endl;
    if(finout.eof())
    {
        finout.clear(); //clear eof flag
    }

    cout << "Enter planet name: ";
    cin.get(pl.name, LIM);
    eatline();
    cout << "Enter planetary population: ";
    cin >> pl.population;
    cout << "Enter planet's acceleration of gravity: ";
    cin >> pl.g;
    finout.seekp(place);    //go back
    finout.write((char *)&pl, sizeof pl) << flush;
    if(finout.fail())
    {
        cerr << "Error on attempted write" << endl;
        exit(EXIT_FAILURE);
    }

    //show revised file
    ct = 0;
    finout.seekg(0);    //go to beginning of file
    cout << "Here are the new contents of the " << file << " file:\n";
    while(finout.read((char *)&pl, sizeof pl))
    {
        cout << ct++ << ": " << setw(LIM) << pl.name << ": "
             << setprecision(0) << setw(12) << pl.population
             << setprecision(2) << setw(6) << pl.g << endl;
    }
    finout.close();
    cout << "Done." << endl;

    return 0;
}

 

posted @ 2013-11-08 15:51  瓶哥  Views(688)  Comments(0Edit  收藏  举报