0

I have some code for Windows that opens a file as an fstream object using ios::in|ios::out|ios::binary. I'm trying to peek 1 byte, change it and write it back to the file in the same position. This is the relevant code (note: _SH_DENYWR is the Windows share mode so I can write to the file but other processes cannot):

this->m_File.open(filename, ios::in | ios::out | ios::binary, _SH_DENYWR);

...

// Using peek here causes all subsequent writes to fail
// even though peek returns the correct value and is not 
// peeking at the EOF
BYTE byte = this->m_File.peek();
BYTE high = binPattern[0].High;
BYTE low = binPattern[0].Low;
BYTE finalByte = byte;

if (high != this->WILDCARD && (byte >> 4) != high)
    finalByte = (finalByte & 0x0f) | (high << 4);

if (low != this->WILDCARD && (byte & 0x0f) != low)
    finalByte = (finalByte & 0xf0) | low;

this->m_File.write((char*)&finalByte, sizeof(BYTE));

// This seekp resets something in the stream and allows the next write to succeed
this->m_File.seekp(this->MAGIC_OFFSET, ios::beg);
this->m_File.write((char*)&this->PATCH_MAGIC, sizeof(DWORD));

...

What am I doing wrong with peek and write?

vane
  • 2,125
  • 1
  • 21
  • 40
  • You are using a write operatiom after a read operation without an intervening seek operation. That's *exactly* what is wrong. It is specifically not allowed. – n. m. could be an AI Apr 23 '20 at 21:08
  • @n.'pronouns'm. Is there any documentation that clearly states that? I want to fully understand what's going on here – vane Apr 23 '20 at 21:09
  • 2
    Here's some good coverage: https://stackoverflow.com/questions/17536570/reading-and-writing-to-the-same-file-using-the-same-fstream – user4581301 Apr 23 '20 at 21:15
  • @user4581301 thanks you for the link, that was really helpful! What would be the proper way to peek a byte without moving the offset and then write that byte back to the same position? Is the best way really to call `peek/get/read` and then `seekp(-1, ios::cur)` before the write? – vane Apr 23 '20 at 21:27
  • `peek` doesn't move the position indicator. Never tried this, so I have no clue if it'll work and not be optimized out, but you can `seekp(0, std::ios::cur)`, seek to the current location. – user4581301 Apr 23 '20 at 22:52
  • @user4581301 I tried that already and unfortunately it doesn't work, you actually have to move the position. I rewrote the whole thing to just read the data into memory, modify it then seek and write it all at once. The amount of data is small so it's not a big deal – vane Apr 23 '20 at 23:59

0 Answers0