-2

I was answering pset4 when they asked me to reverse a WAV file. I got to work and made a code with seemingly no mistakes at all. Here is the code:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

#include "wav.h"

int check_format(WAVHEADER header);
int get_block_size(WAVHEADER header);

int main(int argc, char *argv[])
{
    // Ensure proper usage
    if (argc != 3) {
        printf("Usage: ./reverse input.wav output.wav\n");
        return 1;
    }

    // Open input file for reading
    // TODO #2
    char *file = argv[1];
    FILE *inptr = fopen(file, "rb");

    if (inptr == NULL) {
        printf("Could not open\n");
        return 1;
    }
    // Read header
    // TODO #3
    WAVHEADER header;
    fread(&header, sizeof(WAVHEADER), 1, inptr);

    // Use check_format to ensure WAV format
    // TODO #4
    if (check_format(header) == 0) {
        printf("Error.");
        return 1;
    }
    if (header.audioFormat != 1) {
        printf("Error.");
        return 1;
    }

    // Open output file for writing
    // TODO #5
    char *outfile = argv[2];
    FILE *outptr = fopen(outfile, "wb");

    if (outptr == NULL) {
        printf("Could not open\n");
        return 1;
    }

    // Write header to file
    // TODO #6
    fwrite(&header, sizeof(WAVHEADER), 1, outptr);
    // Use get_block_size to calculate size of block
    // TODO #7
    int size = get_block_size(header);

    // Write reversed audio to file
    // TODO #8
    if (fseek(inptr, size, SEEK_END)) {
        printf("Error.");
        return 1;
    }
    else {
        BYTE buffer[size];
        while(ftell(inptr) - size > sizeof(header)) {
            if (fseek(inptr, - 2 * size, SEEK_CUR)) {
                return 1;
            }
            fread(buffer, size, 1, inptr);
            fwrite(buffer, size, 1, outptr);
        }
        fclose(outptr);
        fclose(inptr);
    }
    return 0;
}

int check_format(WAVHEADER header)
{
    if (header.format[0] == 'W' && header.format[1] == 'A' && header.format[2] == 'V' && header.format[3] == '\0') {
        return 1;
    }
    return 0;
}

int get_block_size(WAVHEADER header)
{
    // TODO #7
    int size = header.numChannels * header.bitsPerSample / 8;
    return 0;
}

but for some reason, to my suprise, when i ran check50, it gave me these results:

:) reverse.c exists
:) reverse.c compiles
:) reverse.c handles lack of input file
:( reverse.c creates an output file
    expected exit code 0, not 1
:| reverse.c writes WAV header to output file
    can't check until a frown turns upside down
:| reverse.c reverses ascending scale
    can't check until a frown turns upside down

i looked at everything in the code, changed some things, looked at many tutorials, but alas, none could get me to a solution.

  • 1
    Is it expected that `get_block_size()` will always ignore the value it calculates and return `0` ? – Jeremy Friesner May 02 '23 at 00:27
  • "made a code with seemingly no mistakes at all." How did you confirm this? Did you run the program against some test files and inspect the results in a hex viewer? Or did you try playing it and listen to the result? Did you take a WAV file and reverse it, then reverse it a second time to confirm you got the original file back? – Raymond Chen May 02 '23 at 00:53
  • step through with your debugger. Step through check_header – pm100 May 02 '23 at 05:40

1 Answers1

1

According to the task description, the bytes at offset 8 to 11 are 'W', 'A', 'V', 'E', not 'W', 'A', 'V', '\0'. It is not a null-terminated string.

Due to you code incorrectly expecting format[3] (which is the byte at offset 11) to have the value '\0', your function check_format incorrectly reports failure, causing your function main to execute return 1;. This is what check50 is complaining about when it writes:

expected exit code 0, not 1

This error is easy to diagnose when running your program line by line in a debugger. The CS50 course teaches you in week 2 how to use the debugger.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39