Search code examples
c++filestreamfstream

C++ file stream for reading/writing


I need to open a file for both reading/writing using fstream and read each character then write that character back to the file. for example i have this code.

fstream in("test.txt",ios::in | ios::out);
if(!in)
    cout<<"error...";
else
{
    char ch;
    in.seekg(0,ios::end);
    int end=in.tellg();//get the length

    in.seekg(0);//get back to the start
    for(int i=0;i<end;i++)
    {
       //in.seekg(in.tellg());//if i uncomment this the code will work
       if(!in.get(ch).fail())//read a character
       {
           in.seekp(static_cast<int>(in.tellg())-1);//move the pointer back to the previously read position,so i could write on it
           if(in.put(ch).fail())//write back,this also move position to the next character to be read/write
               break;//break on error
       }
    }
}

I have a file named "test.txt" which contains "ABCD". As i understand it both put() and get() methods of the stream object move the file pointer forward(i see that by getting the return value of tellg() or tellp() functions after each get() or put() method call). My question is when i comment out the code that will seek the stream pointer to "where it is now"(in.seekg(in.tellg()), the code will result incorrect results. I don't understand why this is since tellg() is showing the correct position of the character to be read next.what is the purpose of explicitly seeking to it? I am using visual studio 2005.

The incorrect result is it writes to the file "ABBB" instead of "ABCD".


Solution

  • The output buffer has to be flushed when switching between write and read.

    fstream in("test.txt",ios::in | ios::out);
    if(!in)
       cout<<"error...";
    else
    {
       char ch;
       in.seekg(0,ios::end);
       int end=in.tellg();//get the length
    
       in.seekg(0);//get back to the start
       for(int i=0;i<end;i++)
       {
          if(!in.get(ch).fail())//read a character
          {
              in.seekp(static_cast<int>(in.tellg())-1);//move the pointer back to the previously read position,so i could write on it
              if(in.put(ch).fail())//write back,this also move position to the next character to be read/write
               break;//break on error
    
              in.flush();
          }
       }
    }