C++/I/O

Advertisement


Question
hello

after executing the following code

ifstream infile;
...

while(!infile.eof()){
     //read each character inside file
}

how can i go back to the beginning of the file?
(i want to read the first character of the file)

thanks

Answer
I suggest you try:

   infile.seekg(0, std::ios::beg);

I am assuming ISO standard C++ IOStreams and not any form of pre-standard IOStreams (sometimes called traditional IOStreams) - that is you included the standard header <fstream> (note: no .h extension) not something like <fstream.h>, and have used a using directive for namespace std:

   using namespace std;

Or a using declaration for std::ifstream:

   using std::ifstream;

If you are using an old, pre-standard version of IOStreams, then the solution could be similar - maybe without the std:: namespace qualification, or you may have to obtain a pointer to the file buffer (of type filebuf) by calling rdbuf and call its seekoff member:

   // Possible use for pre-standard IOStreams
   infile.rdbuf()->seekoff(0, ios::beg, ios::in);

The example above would seem correct for a pre-standard IOStreams implementation shipped with a Watcom compiler - if I have read the manual correctly. I used this as an example as I have the manual available. However as I no longer use pre-standard compilers I cannot check it is correct, and have forgotten much detail from that time - sorry!

In either case the file read position is positioned 0 bytes from the beginning of the file - this is what the 0 and (std::)ios::beg parameter values mean.

Other interpretations of the position value other than from the beginning of the file can be used by specifying different values for the second parameter. To have the position value be used relative to the end of the file use (std::)ios::end (which implies pos should be <= 0). To have the position value be interpreted relative to the current position use (std::)ios::cur.

Note: I am placing the qualification of the std:: namespace in () as it may not be required, however strictly it is part of the fully qualified names of ios::beg, ios::end, and ios::cur for standard C++ IOStream implementations. That is they are std::ios::beg, std::ios::end and std::ios::cur.

For standard C++ IOStream implementations there are separate file positions for reading and writing (or getting and putting). This is the reason the seekg operation has a g on the end - seek get position. This implies there would be a seek put position for writing and indeed there is: std::fstream objects (including std::ifstream and std::ofstream) have a seekp member function, for example:

   outfile.seekp(0, std::ios::end); // position to end of file

To go with the operations to modify the file read and write positions are operations to return their current values. These are the tell member functions tellg and tellp:

   std::streampos read_pos = infile.tellg();
   std::streampos write_pos = outfile.tellp();

These position values can then be used with seekp and seekg.

For the record I should point out that the example using traditional IOStreams affects both the read and write position. The third argument to the traditional filebuf::seekoff function should specify which position (read or write or both) is affected but the documentation for this implementation states that the get and put areas are tied together so there is only one file position that covers both read and write, hence the third parameter is ignored.

Also for the record I should point out that the standard C++ IOStreams are similar to the older IOStreams library, and so we can also change the file read and write position using stream (file) buffers in standard C++ IOStreams. In fact it is a stream's associated stream buffer that does all the real work and different buffer types allow streams to work with different storage devices - such as strings and files. The details for using a std::filebuf are a little different to the traditional filebuf. The member function rdbuf is still used to access the stream object associated with a stream, but the operations on a standard filebuf are a little different:

   // Standard C++ IOStream file positioning
   // using std::filebuf steam buffer:

   // Position to the 0th absolute file position
   // for both read and write
   infile.rdbuf()->pubseekpos(0);

   // Position to the 0th absolute file position
   // for both read only
   infile.rdbuf()->pubseekpos(0, std::ios_base::in);

   // Position to the 0th file position from the beginning of file
   // for both read and write
   infile.rdbuf()->pubseekoff(0, std::ios::beg);

   // Position to the 0th file position from the beginning of file
   // for both read only
   infile.rdbuf()->pubseekoff(0, std::ios::beg, std::ios_base::in);

Note: rdbuf returns a pointer to the stream's associated stream buffer. As it is a pointer it could possibly be a null pointer value (although it should not be if the stream is functioning correctly!). I have not bothered to check that rdbuf returns a valid pointer in my example code for brevity.

Also a std::filebuf _does_ have separate get and put areas and these may not be tied together and only one area may be active at a time. I am not going to go into the gory details here - as I would first have to revise them myself and the details of just how a filebuf object works with input, output and switching between the two is quite complex for a Q and A forum like this, and you really do have to have your brain in gear to follow it through!! (my IOStream text here - "Standard C++ IOStreams and Locales" by Langer and Kreft - takes over 10 pages with 15 diagrams to describe the behaviour of an example implementation of filebuf)

In short then I hope you are using a standard C++ IOStreams implementation and therefore do not have to bother with filebufs, as this is obviously the most convenient interface to use (which I suppose is why it was included!) - if you are like me you probably think that dropping down to the stream buffer level just to do something so simple is a bit over the top!

Finally I should note that you can of course re-position the file pointer to the start of the file by simply closing and re-opening the file for reading:

   infile.close();
   infile.open( filepathname );

   if ( infile.is_open() )
   {
   // proceed...
   }
   else
   {
   // handle unable to open file error
   }

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.