This code worked for me when tested on an Ubuntu 12.04 derivative with GCC 4.9.0:
#include <iostream>
#include <stdio.h>
using namespace std;
int main(int argc, char* argv[])
{
if (argc != 2)
{
cerr << "Usage: " << argv[0] << " file\n";
return 1;
}
FILE *fSource = fopen(argv[1], "r+");
if (fSource == NULL)
{
cerr << "Can't open file: " << argv[1] << "\n";
return 2;
}
int c;
int i = 0;
while ((c = fgetc(fSource)) != EOF)
{
char b = c ^ 0x13;
fseek(fSource, i++, SEEK_SET);
fwrite(&b, 1, sizeof(b), fSource);
fseek(fSource, i, SEEK_SET);
}
fclose(fSource);
cout << "Fuzzed: " << argv[1] << "\n";
return 0;
}
It reports file names; it reports errors to standard error (cerr
); it uses int c;
to read the character, but copies that to char b
so that the fwrite()
works. When run on (a copy of) its own source code, the first time the output looks like gibberish, and the second time recovers the original.
This loop, using fputc()
instead of fwrite()
, also works without needing the intermediate variable b
:
while ((c = fgetc(fSource)) != EOF)
{
fseek(fSource, i++, SEEK_SET);
fputc(c ^ 0x13, fSource);
fseek(fSource, i, SEEK_SET);
}
The use of an fseek()
after the read and after the write is mandated by the C standard. I'm not sure whether that's the main cause of your trouble, but it could in theory be one of the issues.