1

I'm writing a function that gets a binary file with integers and reverses their order. For example, I have this binary file (in hexadecimal):

00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04

and I want it to be:

00 00 00 04 00 00 00 03 00 00 00 02 00 00 00 01

But with my algorithm I get this:

00 00 00 01 00 00 00 02 00 00 00 03 00 00 00 04 CC CC CC CC 00 00 00 00  CC CC CC CC

And I don't get why... This is my algorithm:

void reverse(FILE * fr)
{
    int i, num1, num2, fileLength;
    fseek(fr, 0, SEEK_END);
    fileLength = ftell(fr) / sizeof(int);
    for(i = 0; i < fileLength / 2; i++)
    {
        fseek(fr, i * sizeof(int), SEEK_SET);
        fread(&num1, sizeof(int), 1, fr);
        fseek(fr, i * sizeof(int), SEEK_END);
        fread(&num2, 4, 1, fr);
        fseek(fr, i * sizeof(int), SEEK_END);
        fwrite(&num2, sizeof(int), 1, fr);
        fseek(fr, i * sizeof(int), SEEK_SET);
        fwrite(&num1, sizeof(int), 1, fr);
    }
}
int main()
{
    FILE * f = fopen("test.bin", "r+b");
    reverse(f);
    fclose(f);
    getchar();
    return 0;
}

What am I doing wrong?

EDIT: I am given a file size that divides by sizeof(int).

EDIT 2:

After changing the code as pts pointed out, it still doesn't work. it outputs:

CC CC CC CC CC CC CC CC 00 00 00 03 00 00 00 04 00 00 00 01 00 00 00 00 00 00 00 02

my edited code is shown above.

(By the way, to all the commenters, I was told not to read the whole file to memory and then reverse it because it's supposed to be an excercise in file manipulation, not in memory manipulation.)

Thanks.

shoham
  • 792
  • 2
  • 12
  • 30
  • Your solution is incorrect unless the file size is divisible by `sizeof(int)`. – pts Jun 18 '14 at 12:11
  • 1
    Your solution is very slow, because it seeks too often. You should read at least 8 kB at a time, but preferably much more (8 MB). – pts Jun 18 '14 at 12:13
  • 1
    This is horrible. Seriously consider reading the whole file in, swapping the bytes in memory, and writing them all out. Doing in-place file modification is really scary. – unwind Jun 18 '14 at 12:24
  • The value 0xCC everywhere is most likely due to uninitialized variables http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new – phuclv Jun 18 '14 at 13:23
  • and why do you reverse each 4 bytes instead of bytes? Note that int is not always 32 bits – phuclv Jun 18 '14 at 13:24
  • Minor: `i, fileLength` should be `long`. – chux - Reinstate Monica Jun 18 '14 at 14:31
  • 1
    @LưuVĩnhPhúc It's not always 32 bits, but it's always sizeof(int). – shoham Jun 18 '14 at 18:08

2 Answers2

3

try this:

void reverse(FILE * fr)
{
    int i, num1, num2, fileLength;
    fseek(fr, 0, SEEK_END);
    fileLength = ftell(fr) / sizeof(int);
    for(i = 0; i < fileLength / 2; i++){
        fseek(fr, i * sizeof(int), SEEK_SET);
        fread(&num1, sizeof(int), 1, fr);
        fseek(fr, (-1-i) * sizeof(int), SEEK_END);
        fread(&num2, sizeof(int), 1, fr);
        fseek(fr, (-1-i) * sizeof(int), SEEK_END);
        fwrite(&num1, sizeof(int), 1, fr);
        fseek(fr, i * sizeof(int), SEEK_SET);
        fwrite(&num2, sizeof(int), 1, fr);
    }
}

int, int, int, int[EOF]
                  ^fseek(filep, 0, SEEK_END)
               ^
               fseek(filep, -1*sizeof(int), SEEK_END)
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0

In the middle you have to seek again. Also the use of num1 and num2 is wrong when writing.

    fread(&num2, 4, 1, fr);
    fseek(fr, i * sizeof(int), SEEK_END);  // Add this.
    fwrite(&num1, sizeof(int), 1, fr);     // num1.
    fseek(fr, i * sizeof(int), SEEK_SET);
    fwrite(&num2, sizeof(int), 1, fr);     // num2.
pts
  • 80,836
  • 20
  • 110
  • 183
  • Oh, I forgot reading and writing moves the cursor of the file. Thanks. – shoham Jun 18 '14 at 12:19
  • Not explained here, not explained there either actually, but still, at least there are some words there stating that a seek is necessary while switching between reading and writing: http://stackoverflow.com/a/14878976/2736228 – Utkan Gezer Jun 18 '14 at 12:20