views:

599

answers:

4

Hi I wanted to know if it's possible to read a byte from a binary file with "fstream" and then change that byte and write it back. I tried this code but it didn't work and nothing happens but I'm sure it reads correctly.

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
file.seekg(0, ios::end);
int size=file.tellg();
file.seekg(0,ios::beg);
char buffer;    
for(int i=0;i<size;i++)
{
    file.read((char*)&buffer,sizeof(char));
    buffer=(buffer+7)%256;
    file.write((char*)&buffer, sizeof(char));
}

should I take the file pointer one byte back after reading like this:

file.seekg(-1, ios::cur);

Thanks in advance.

+6  A: 

Yes. As you suggested in the question, you need to adjust the position of the file pointer using seekg if you want to overwrite the previously read bytes. After each read, the file pointer would be positioned after the read bytes.

Yukiko
+1  A: 

Reading and writing uses the same position pointer. Hence, if you want to be able to read consecutive values, to rewrite a value you are expected to rewind the pointer to the position that was read, right?

That said, in your case it would probably be more efficient to read blocks of data, then convert them in memory, and then write them back.

Kornel Kisielewicz
+2  A: 

You should move back the pointer the amount of previous read bytes; so with char -1.

file.seekg(-1, std::ios::cur);

Do consider that when modifying data it has to have the same byte size, or you'll overwrite other data in your file.

Chaoz
A: 

Firstly you must ALWAYS check the file actually opened:

file.open(path, ios::in|ios::out|ios::binary|ios::ate);
if ( ! file.is_open() ) {
    throw "open failed";
}

Then you must ALWAYS check that reads & writes that you expect to work have worked:

if ( ! file.read((char*)&buffer,sizeof(char)) ) {
   throw "read failed";
}

And lastly, you should check that the combination of open flags you are using is valid on your particular platform - see http://stackoverflow.com/questions/2305480/stdgetline-doesnt-read-anything for some discussion of this - I would suggest removing the ios::ate flag in your code.

anon