You are here:

C++/file handling in C++

Advertisement


Question
I have made a generic template class for  1D array.This array can be any type of inbuilt data type..I have to save and load the object of class in a file.Please tell  me how to make these functions. Also answer me this probliem in context of a class only having integer type 1 D array

Answer
You do not say what format you wish to save the data as so I shall assume usual C++ practice and advise that you create operator<< and operator>> function overloads for your (generic) class. If your class template is oneDArray<T> then for the case of oneDArray<int> we would write operator<< and >> function overload thus:

std::ostream & operator<<(std::ostream & out, oneDArray<int> const& a);
std::istream & operator>>(std::istream & in,  oneDArray<int> & a);

You can then pass objects of type std::ofstream, std::ifstream and std::fstream (include <fstream>) to these functions as appropriate. These being the file handling stream types, you would first open the file to write to or read from then pass the stream object to one of these operator functions which would usually look something like the following:

   std::ofstream out("array.dat");
   oneDArray<int> array;

   // Add elements to the array...

   if ( out && out.is_open() )
   {
       out << array;
   }



   std::ifstream in("array.dat");

   oneDArray<int> array;
   if ( in && in.is_open() )
   {
       in >> array;
   }

The above are two separate snippets of code and not in the same scope (e.g. in different functions). By the way, the code snippets I show here are straight out of my head and so may contain mistakes and typos so I apologise if this is the case...

This only leaves the problem of how to write and read the data from the array class into the array. I cannot show you how to do this for sure as I do not know what the interface to your array class template is. However the basic idea is to use the existing support for reading and writing data to streams using existing operator<< and operator>> overloads for the array element type.

For writing to a stream (i.e. operator<<):

   For each element in the array
       out << element << '\n';
       If out stream not good break out of loop
   End For each
   Return out

And for reading from a stream (i.e. operator>>):

   While stream good (including not at end of file)
       in >> value;
       If in stream good append value to end of array
   End While
   Return in

Note that reading data into an array is different from writing out from an array.

In the writing case all the elements exist so we can just access them and pass the values to the stream and separate each element written out with white space - a newline in this case. White space is used as a separator because it is the default separator used when reading values from an input stream using operator>>. The only problem for basic types comes with strings containing white space of course, but here you are interested in integer data only so this is not going to be a problem.

In the reading case we have to read data from the file until the file is exhausted - that is at end of file. I have chosen to read data from the file until the stream enters any non-good state - be it end of file, bad formatting of data or a fatal stream error. Having read a value it has to be appended to the array object. I assume here that your array type works a little like std::vector in this respect and some special operation has to be performed to add new elements to an array by appending them which may cause re-allocations of memory and copying of existing element data to a new, larger area of memory (if your array does not work in this way then you will have to modify the pseudo code as appropriate). Such allocations of course can fail and so reading data may fail due to memory exhaustion as well as problems with the stream.

Note that this is the simplest scheme I could think of. You can of course make it more complex by addition additional code - maybe you wish the elements separated by commas or something, maybe you wish to add special tokens indicating strings in the data etc. etc. In such cases it may be better to read the file a whole line at a time and parse each line for the data it contains.

If your one dimensional array were std::vector<int> (include <vector>) then the operator<< and >> functions would look something like this:

std::ostream & operator<<
( std::ostream & out
, std::vector<int> const & a
)
{
   for ( int i(0); i!=a.size(); ++i)
   {
       out << a[i] << '\n';
       if ( !out.good() )
       {
         break;
       }
   }
   return out;
}

std::istream & operator>>(std::istream & in, std::vector<int> & a)
{
   while ( in.good() )
   {
       int value;
       in >> value;
       if ( in.good() )
       {
         a.push_back(value);
       }
   }
   return in;
}

They can be used like so:

int main()
{
   {
     std::vector<int> arrayOfInts;

     arrayOfInts.push_back(99);
     arrayOfInts.push_back(999);
     arrayOfInts.push_back(9999);

     OutVec(std::cout, "arrayOfInts to be written", arrayOfInts );

     std::ofstream out("vectorint.dat");

     if ( out && out.is_open() )
     {
         out << arrayOfInts;
     }

     arrayOfInts.clear();
     OutVec(std::cout, "arrayOfInts cleared", arrayOfInts );
   }

   {
     std::vector<int> arrayOfInts;
     std::ifstream in("vectorint.dat");

     if ( in && in.is_open() )
     {
         in >> arrayOfInts;
     }
     OutVec(std::cout, "arrayOfInts read", arrayOfInts );
   }
}

The additional apparent redundant braces around reading and writing code form explicit scopes within the main function. This ensures local objects are destroyed - closing file streams, deleting vectors etc. between the writing and reading of array data.

Obviously you would replace the usage of std::vector with that of your own class template. Note also that other facilities of the standard library make using the standard containers with streams even easier, e.g. by using input and output stream iterators and inserter iterator adapters. However I have purposely not used these facilities as I have had to assume that your array class template is not compatible with such features.

Finally consider what effect changing the declaration of the operator<< and >> functions to make them function templates would have:

template <typename T>
std::ostream & operator<<(std::ostream & out, oneDArray<T> const & a);

template <typename T>
std::istream & operator>>(std::istream & in,  oneDArray<T> & a);

Would you need any changes to the implementation? Would you require additional specific overloads (e.g. for arrays of char *, C style strings, for example)?

Hope this helps.  

C++

All Answers


Answers by Expert:


Ask Experts

Volunteer


Ralph McArdell

Expertise

I am a software developer with more than 15 years C++ experience and over 25 years experience developing a wide variety of applications for Windows NT/2000/XP, UNIX, Linux and other platforms. I can help with basic to advanced C++, C (although I do not write just-C much if at all these days so maybe ask in the C section about purely C matters), software development and many platform specific and system development problems.

Experience

My career started in the mid 1980s working as a batch process operator for the now defunct Inner London Education Authority, working on Prime mini computers. I then moved into the role of Programmer / Analyst, also on the Primes, then into technical support and finally into the micro computing section, using a variety of 16 and 8 bit machines. Following the demise of the ILEA I worked for a small company, now gone, called Hodos. I worked on a part task train simulator using C and the Intel DVI (Digital Video Interactive) - the hardware based predecessor to Indeo. Other projects included a CGI based train simulator (different goals to the first), and various other projects in C and Visual Basic (er, version 1 that is). When Hodos went into receivership I went freelance and finally managed to start working in C++. I initially had contracts working on train simulators (surprise) and multimedia - I worked on many of the Dorling Kindersley CD-ROM titles and wrote the screensaver games for the Wallace and Gromit Cracking Animator CD. My more recent contracts have been more traditionally IT based, working predominately in C++ on MS Windows NT, 2000. XP, Linux and UN*X. These projects have had wide ranging additional skill sets including system analysis and design, databases and SQL in various guises, C#, client server and remoting, cross porting applications between platforms and various client development processes. I have an interest in the development of the C++ core language and libraries and try to keep up with at least some of the papers on the ISO C++ Standard Committee site at http://www.open-std.org/jtc1/sc22/wg21/.

Education/Credentials

©2016 About.com. All rights reserved.