Search code examples
ccs50fread

Number of files read is always 0


Here is a little code I wrote. Please note -

  1. The file that is being pointed to by rawbytes > 512 bytes
  2. Do I open the file being read from in "r" or "rb"? I don't know what is in it apart from a couple of JPEGs.
  3. Why does my fread always output 0, even when I make it fread(bytes, 1, 512, rawbytes)?

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

int main(int argc, string argv[])
{
    // Declaring a new type 
    typedef uint8_t BYTE;
    
    // Declaring an array of bytes, in which I want to read 512 bytes
    BYTE bytes[512];
    
    FILE *rawbytes = fopen(argv[1], "rb");
    int numberofbytesread = fread(bytes, 1, 512, rawbytes);
    
    // Check
    printf("%i\n", numberofbytesread);
    fclose(rawbytes);
}

Edit 1: Changed int data type to size_t data type. New code:

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

int main(int argc, string argv[])
{
    // Declaring a new type 
    typedef uint8_t BYTE;

    // Declaring an array of bytes, in which I want to read 512 bytes
    BYTE bytes[512];

    FILE *rawbytes = fopen(argv[1], "rb");
    size_t numberofbytesread = fread(bytes, 1, 512, rawbytes);

    // Check
    printf("%zu\n", numberofbytesread);
    fclose(rawbytes);
}

I don't know what %zu is, but the compiler told me to swap %i with %zu. Still getting 0 bytes read. :(

Edit 2: To make the problem reproducible, I have replaced argv[1] with the memory card file that I'm tasked to 'recover' JPEG files from called card.raw. This code is just a small code I wrote to check whether I'm able to read at least 512 bytes from card.raw

Execute wget https://cdn.cs50.net/2019/fall/psets/4/recover/recover.zip to download a (compressed) ZIP file with this problem’s distribution. Execute unzip recover.zip to uncompress that file.

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

int main(int argc, string argv[])
{
    // Declaring a new type 
    typedef uint8_t BYTE;

    // Declaring an array of bytes, in which I want to read 512 bytes
    BYTE bytes[512];

    FILE *rawbytes = fopen("card.raw", "rb");
    if (rawbytes == NULL)
    {
           return 1;
    }

    size_t numberofbytesread = fread(bytes, 1, 512, rawbytes);

    // Check
    printf("%zu\n", numberofbytesread);
    fclose(rawbytes);
}

Solution

  • here it seems ok

    I tried it here and it worked with a local file. Then I tried this card.raw and it seems ok too. First block is only zeros, 2nd has a surprise, and then it goes on with data.

    second block

    • 3rd block seems to be a valid jpeg signature...

    enter image description here

    • I did not change your code except to display the data
    • compiled just under CL 19.27. No religious discussion here, please.
    • the code just goes reading as long there is data... waits for a key between blocks

    here is the code

    #include <ctype.h>
    #include <stdio.h>
    #include <stdint.h>
    #include <stdlib.h>
    //#include <cs50.h>
    
    int main(int argc, char** argv)
    {
        // Declaring a new type 
        typedef uint8_t BYTE;
    
        // Declaring an array of bytes, in which I want to read 512 bytes
        BYTE bytes[512];
    
        FILE* rawbytes = fopen("card.raw", "rb");
        if (rawbytes == NULL) return 1;
        // ok file is open
        size_t numberofbytesread = 0;
        size_t block = 0;
        char ch;
        while ((numberofbytesread = fread(bytes, 1, 512, rawbytes)) > 0)
        {
            printf("\n%zu bytes read:\n\n\t000    ", numberofbytesread);
            int col = 0;
            for (size_t i = 0; i < numberofbytesread; i += 1)
            {
                if(isprint(bytes[i]))
                    printf("%2c  ", bytes[i]);
                else
                    printf("%02X  ", bytes[i]);
                col += 1;
                if (col % 16 == 0) printf("\n\t%3d    ",i+1);
            };  // for()
            if (col % 16 == 0) printf("\n");
            block += 1;
            printf("Block: %zd. Press ENTER \n", block); 
            ch = fgetc(stdin);
        };
        fclose(rawbytes);
    }