Home Library Index Site Map� Links Contact About

Binary File Input / Output

The example I have written is an implementation of a list container which is initialised with some data and then written to file, read from file and printed.

In practise there would be a number of more efficient, not to mention quicker, ways to implement this but as an example it is a valuable coding exercise.

The guts of the Binary I/O is in the driver and the supporting functions in filio.cpp.

See the notes with the header and driver for an explanation.





Binary I/O Example.
// Headers.
// INCLUDES
#include <iostream.h>
#include <iostream.h>

#include "fileio.cpp"

// handy binary file input/output functions
#include "TDataStr.h" // data struct
// An initialised TDataStruct
#include "DbugList.h"
#include <string.h> // strcpy
#include "LexCmp.cpp"// compares strings

The current stage of development of this code is...

The approach I take for a relatively sequential piece of code
like this linked list, is to use a simple, built in concrete type
when I begin programming.

In this case I started with an int type and wrote the
guts of the linked list code operating on that type.
This allows me to write a structure for the program, and develop
from there without getting too bogged down in implementation.

When we have a working program, irrespective of it's lack of
functionality I either add the final data type, write it's
member functions and test or, templatize it.

From there, I then extend the program to it's final functionality
before I get too involved in, encapsulation, constness and
exception handling.

This particular program is in the functionality extending stage.
If you keep an eye on it you will see I intend to develop it
largely in line with the methods available from the STL list type.

For a more object oriented approach, when using abstract classes
and a class hierarchy for instance, it is obviously essential
to include constness, encapsulation and exception handling at an
early stage.

Home Library Index Top

Binary I/O Example.
// classes.�
// Node List and Itor
// Node
//----------------------------------------------
class Node
{
public:
friend class List;
friend class Itor; TDataStruct Data() {return data;};
void Data(TDataStruct t) {data =t;}; private:
TDataStruct data;
Node *pNext, *pPrev;
};

Back to Top

// List
//---------------------------------------------
class List
{
public:
friend class Itor;
List();
List(int num);
~List() {Clear();}; int Append();
int Pop();
int Clear();
void ShowList(); // debug only
void InitList(); // debug only private:
Node *pNode, *pFirst, *pLast;
int length;
};

// List::List()

//----------------------------
List::List() : pNode(0), pLast(0), pFirst(0)�
{
Node *pNode = new Node; // initialise first empty node
pNode->pNext=0;
pNode->pPrev=0;
pLast =pNode;
pFirst =pNode;
length =1; };

// List::List(int num)
//----------------------------
List::List(int num): pNode(0), pLast(0), pFirst(0)�
{
Node *pNode = new Node; // initialise first empty node
pNode->pNext=0;
pNode->pPrev=0;
pLast =pNode;
pFirst =pNode;
length =1;
for(int i=0; i<num-1; i++) Append();
};

// List::Append() // adds node to end of list
//----------------------------
int
List::Append()
{
Node* pTemp =new Node;
if(!pTemp || !pLast) return 0;

pLast->pNext =pTemp;
pTemp->pNext =0;
pTemp->pPrev =pLast;
pLast =pTemp;

length++;
return 1;
};

// List::Clear();
// clears list
//----------------------------
int
List::Clear()
{
if(!pNode || !pLast) return 0;
pNode =pLast;

while(pNode->pPrev)
{
Pop();
}
length =1;
return 1;
};
//----------------------------

// List::Pop();
// deletes end node

int List::Pop()
{
Node* pTemp =pLast;
pNode =pLast->pPrev;
pNode->pNext =0;
delete pTemp;
pLast =pNode;

length--;
return 1;
};

// List::ShowList() // debug only
//----------------------------
void
List::ShowList()
{
pNode =pFirst;

cout<<"\n\nShowList() "
<<"\n Address\tData\n\n"
<<pNode<<'\t'<<pNode->data.custNo;

cout<<'\t'<<pNode->data.companyName;
while (pNode->pNext)
{
pNode =pNode->pNext;
cout<<'\n'<<pNode<<'\t'<<pNode->data.custNo
<<'\t'<<pNode->data.companyName;
}
};
//----------------------------

// List::InitList()
// debug only
void
List::InitList()
{
pNode =pFirst;
int i=0;
pNode->data.custNo =i;
strcpy(pNode->data.companyName,Companies[i]);
do
{
pNode =pNode->pNext;
i++;
pNode->data.custNo =i;
strcpy(pNode->data.companyName,Companies[i]);

}while(pNode!=pLast);
};
//------------------------------------------------

Back to Top

// Itor
class Itor
{
public:
Itor(List& rL) : list(rL){}; void First(){pCur =list.pFirst;};
void Last(){pCur =list.pLast; cout<<'\n'<<pCur;};
int Attach(TDataStruct& t);
// int Detach();
Node* Cur(){/*cout<<"\npCur =="<<pCur;*/ return pCur;};
const List& GetList() {return list;};

void operator--(){pCur =pCur->pPrev;};
void operator++(){pCur =pCur->pNext;};
private:
Node *pCur;
List& list;
};

// Itor::Attach()
//----------------------------
int
Itor::Attach(TDataStruct& t)
{
First();
if(!pCur) return 0;

while(LexCmp(t.companyName, pCur->Data().companyName)>0)
{
if(!pCur->pNext) // at end
{
ist.Append();
Last();
pCur->Data(t);
return 2;
}
pCur= pCur->pNext;
}

if(!pCur->pPrev) // at beginning
{
Node* pTemp =new Node;

pTemp->pPrev =0;
pTemp->pNext =pCur;
pCur->pPrev =pTemp;

pCur=pTemp;
pCur->Data(t);

list.pFirst =pCur;
list.length++;

return 1;
}
else
{
pCur=pCur->pPrev;
Node* pTemp =new Node;
pTemp->pNext =pCur->pNext;
pTemp->pPrev =pCur;
pCur->pNext->pPrev =pTemp;
pCur->pNext=pTemp;

pCur=pTemp;
pCur->Data(t);
list.length++;

return 3;
}

}

The classes and functions are written with an eye on reusability. This is only an exercise. Using the STL list or map class would be more useful.�
Home Library Index Top

Binary I/O Example
// Driver for testing linked list

void main()
{
const int LEN=10;
List outlist(LEN), inlist(LEN); // 2 x lists
Itor Output(outlist), Input(inlist); // 2 x Itors
outlist.InitList(); // initialise outlist
outlist.ShowList(); // display it
Output.First(); // set listPos to list ofstream data_output;�
ifstream data_input;

OpenBinFileOut(data_output,"TEST.BIN");

for(int i=0;i<LEN;i++)
{
WriteStruct(Output.Cur()->Data(), data_output);
Output++;
}
data_output.close();

OpenBinFileIn(data_input,"TEST.BIN");
Input.First();
TDataStruct temp;
for(int i=0;i<LEN;i++)
{
ReadStruct(temp, data_input);
Input.Cur()->Data(temp);
Input++;
}
data_input.close();

inlist.ShowList();
while(!cin.get())
;
}; // MAIN

What's happening?

Using some handy functions I wrote in fileio.cpp the driver first
initialises some data and writes it to file.

The file is then re-opened and the data read into another
list and displayed.
Home Library Index Top



STL Database
Arrays
Binary File Input / Output
Character Input
Containers
Standard Template Library
Streams
Templates
Utility Functions
Win32 Programming
Miscellaneous

 
copyright notice

Copyright Robert Mitchell. Last Revised : 28 April, 2000

e-mail me
Hosted by www.Geocities.ws

1