captain monk
captain monk

Reputation: 727

fread fwrite fseek in C

Hello what i am trying to do is to reverse a binary file. The type of the file is wav so for example if the channel number is 2 and bits per sample are 16 each time i will copy 32/8 = 4 bytes. The first think to do is copy the header as it is(that part is ok) and then reverse he data. I've created a code to copy the header and then part of the data from the end this 10 times(for testing) but instead of copying 40 bytes it stops at 20 for some reason(even if it would do it 20 times it would still copy just the 20 bytes). This is the code which does that. I can't spot the mistake if you can see it tell me :) Maybe the mistake is somewhere else so i wrote the full function

void reverse(char **array)
{
    int i=0;
    word numberChannels;
    word bitsPerSample;
    FILE *pFile;
    FILE *pOutFile;
    byte head[44];
    byte *rev;
    int count;
    if(checkFileName(array[2]) == 0 || checkFileName(array[3]) == 0)
    {
        printf("wrong file name\n");
        exit(1);
    }
    pFile = fopen (array[2] ,"r");
    fseek(pFile, 22, SEEK_SET);//position of channel
    fread(&numberChannels, sizeof(word), 1, pFile);
    fseek(pFile, 34, SEEK_SET);//position of bitsPerSample
    fread(&bitsPerSample, sizeof(word), 1, pFile);
    count = numberChannels * bitsPerSample;
    rewind(pFile);
    fread(head, sizeof(head), 1, pFile);
    pOutFile = fopen (array[3] ,"w");
    fwrite(head, sizeof(head), 1, pOutFile);
    count = count/8;//in my example count = 32 so count =4
    rev = (byte*)malloc(sizeof(byte) * count);//byte = unsigned char
    fseek(pFile, -count, SEEK_END);
    for(i=0; i<10 ; i++)
    {
        fread(rev, count, 1, pFile);
        fwrite(rev, count, 1, pOutFile);
        fseek(pFile, -count, SEEK_CUR);     
    }
    fclose(pFile);
    fclose(pOutFile);
}

Upvotes: 0

Views: 2125

Answers (3)

Maxime Ch&#233;ramy
Maxime Ch&#233;ramy

Reputation: 18821

I would change your fseek to move relatively from the current position (and use count instead of sizeof(rev)):

for(i=0; i<10; i++)
{
    fread(rev, count, 1, pFile);
    fwrite(rev, count, 1, pOutFile);
    fseek(pFile, -count, SEEK_CUR);
}

Upvotes: 1

ctn
ctn

Reputation: 2930

You need to initialize count to 4 and add 4 to it progressively. Also, sizeof(rev) is only the size of a pointer (4/8 bytes). You need to use sizeof(byte) * count instead. You can also use count in the for directly:

pFile = fopen(array[2] ,"r");
pOutFile = fopen(array[3] ,"w");
rev = (byte*)malloc(sizeof(byte) * count); //byte = unsigned char
for(count = 4; count < 44; count += 4)
{
    fseek(pFile, -count, SEEK_END);
    fread(rev, sizeof(byte), count, pFile);
    fwrite(rev, sizeof(byte), count, pOutFile);
}
fclose(pFile);
fclose(pOutFile);

Upvotes: 0

Drew McGowen
Drew McGowen

Reputation: 11706

sizeof(rev) will evaluate to the size of a pointer. You probably just want to use count instead.

Also, does the line count = count + count do what you want it to? (i.e. it doubles count every iteration)

Upvotes: 1

Related Questions