You are here:

C++/write/read same file in the same .cpp program

Advertisement


Question
I am trying to create an output file from the user input. Then I'd like to use this output file as an input file so that I can generate another file by processing the info in the input file. In the same c++ file can I achieve it and if yes, how? ( i tried fstream but didnt work).
thanks for your help,

I am using gnu compiler to compile my .cpp prgram. if you can give me an example on how to do it that would be very helpful.  

Answer
Well you have two main approaches to this, both will work with the C++ IO Streams file streams.

First you can:

- open you file for writing
- write the data to the file
- close the file when done writing the data

- open the file for reading
- read the data
- close the file when done

Note that you should close the file between writing it and reading it - having to do this depends on the file sharing modes for your operating system. Usually you can have one writer _or_ one or more readers. So if you have the file open for writing on one stream you cannot open it for reading until the writing stream has been closed.

This leads to the second approach - instead of opening the file for writing to start with you can open it for reading and writing:

- open the file for reading and writing
- write the data to the file

- when you are done re-wind the file read position to the file start

- read the data from the file

- close the file

The choice really depends on how your program operates. If there is a delay between writing the data and reading it you might like to use the first option to ensure the data is saved on disk and resources - such as file buffer memory - are reclaimed. However, if you intend to read the data immediately after it is written then the second approach would seem better suited.

Here is an example using std::ofstream and std::ifstream to demonstrate the first approach and std::fstream to demonstrate the second:

       #include <fstream>
       #include <iostream>
       #include <string>

       void Approach1();
       void Approach2();

       void ProcessLine( std::string const & lineData );

       int main()
       {
         // Use first approach to write and read file
         std::cout << "Output from first approach:\n";
         Approach1();

         // Use second approach to write and read file
         std::cout << "\nOutput from second approach:\n";
         Approach2();
       }

       // Write and read file using first approach.
       // Create a std::ofstream, write data to it and close stream.
       // Open file using a std::ifstream, read and process lines
       // from it.
       void Approach1()
       {
         // Open file for writing, truncating file data
         // if file exists.
         std::ofstream out("approach1.dat");

         // Write 4 lines to it
         out << "line1\nline2\nline3\nline4\n";

         // Explicitly close out file stream
         // Would also be closed on destruction of object out
         out.close();

         // Open file for reading
         std::ifstream in("approach1.dat");

         // Read and process data in file
         std::string lineData;
         while (in)
         {
         in >> lineData;

         if ( !in )
         {
         if ( !in.eof() )
         {
         std::cerr << "Error! Input "
         "stream failure. "
         "Quitting.\n";
         }
         }
         else
         {
         ProcessLine( lineData );
         }
         }

         in.close();
       }

       // Write and read file using second approach
       // Create a std:fstream, open for read write.
       // Write data, rewind read position and read
       // and process lines in file.
       void Approach2()
       {
         // Open file for reading and writing,
         // with truncation of existing file data
         std::fstream inOut( "approach2.dat"
         , std::ios::in | std::ios::out
         | std::ios::trunk
         );

         // Write 4 lines to it
         inOut << "line1\nline2\nline3\nline4\n";

         // Flush buffered written data to file:
         // This is not strictly necessary but shows you
         // how to do it (could also have used std::endl
         // instead of last \n above)
         inOut.flush();

         // Rewind read position to start of file
         inOut.seekg(0);

         // Read and process data in file
         std::string lineData;
         while (inOut)
         {
         inOut >> lineData;

         if ( !inOut )
         {
         if ( !inOut.eof() )
         {
         std::cerr << "Error! Input "
         "stream failure. "
         "Quitting.\n";
         }
         }
         else
         {
         ProcessLine( lineData );
         }
         }

         inOut.close();
       }

       // Process a line of data.
       // If the line starts with "line" then asume it
       // has the correct format and is followed by a
       // single digit. Output this digit to std::cout.
       // otherwise output error to std:cerr.
       void ProcessLine( std::string const & lineData )
       {
         std::string prefix("line");
         if ( 0==lineData.find(prefix) )
         {
         std::cout << "Line value:"
         << lineData.substr(prefix.length(),1)
         << '\n';
         }
         else
         {
         std::cerr << "Error! badly formatted line.\n";
         }
       }

The example uses three helper functions: Approach1 and Approach2 perform the same process on files approach1.dat and approach2.dat using the first and second approaches to the problem as described above. They each call ProcessLine to do some simple (and silly) processing on the lines written to the file; main simple calls Approach1 and Approach2.

As this is an example it does not show full error checking nor necessarily good design. It is (ISO?ANSI) standard C++ as far as I know, and was built using the latest Microsoft C++ compiler. Whether it works for you depends on your version of g++ - version 3.x.x and 4.x.x are probably OK, especially the from the later 3 versions onwards, but version 2.x.x probably does not have that good a standard C++ library (if it had any I forget the details).

Note that with std::fstream we have to specify the open mode as the second parameter to the constructor (or open), whereas for std:ofstream and std::ifstream they default to std::ios::out and std::ios::in respectfully.

The examples write four lines to their data files:

line1
line2
line3
line4

and then reads and performs some processing on each line from the file.  

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.