8

When you do an fread, whether it is in a while loop statement or anywhere else, it will execute the read and will most definitely move the file pointer. The pointer will be repositioned to the first byte following the read. For example, if the pointer is at byte 0, or the start of the file, and fread reads 3 bytes, it will read bytes 0, 1 and 2, and will ...


4

It's a fairly common error with this pset. The last file is one 512 byte block too long. The logic structure of this program is: Read a block of data process the block of data check for EOF When fread executes, it returns the number of elements read (the third parameter). It will read right up to the end of the file successfully. It will only show ...


3

This is a pretty common newbie mistake. Look at this code: //Loop until end of 512 block while (fread(buffer, sizeof(BYTE), 512, memorycard) == 512) { //Read 512 bytes into buffer fread(buffer, sizeof(BYTE), 512, memorycard); This will read 512 bytes into the buffer, and then read another 512 bytes, overwriting the data from the first read. Simply ...


2

Can you give me an example of a filename that is supposed to contain a line feed? sprintf(outfile, "%03i.jpg\n", foundPhoto); As a side note, a programming tip. When you see to nearly identical blocks of code, maybe there's a way to rewrite it more efficiently, using only one block of code. Especially true when there are two blocks of code that ...


2

1 It's not a single char. You've declared an array of 8 chars, which is what you need to hold "000.jpg" {'0', '0', '0', '.', 'j', 'p', 'g', '\0'} 2 bookmark is an array. An array will "decay" to a pointer type when needed. So you can use either. 3 %03d the 03 means you want a 3-digit number which will use leading zeroes. Using d vs i makes no ...


2

The whole problem is given by the following statement: char fileName[7]; The file name is given by seven characters, but you must bear in mind that it is a string, so we need an additional character (end of string \ 0), note that this simple fact causes an indefinite behavior throughout the program because the program does not know where the string ends. ...


2

De Morgan's laws The opposite of buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] & 0xf0) == 0xe0 is buffer[0] != 0xff || buffer[1] != 0xd8 || buffer[2] != 0xff || (buffer[3] & 0xf0) != 0xe0 Notice how !(A && B) is !A || !B, with && turning into || (...


2

In fwrite(inPointer, 1, number, newFilePointer);, inPointer should be buffer, you don't want to write the content of the FILE structure to disk, but the bytes you read. Interesting part is - your pseudo code looks fine, nothing like your actual code. I don't get why you are fopening output files for reading text "r" instead of only writing binary "wb". ...


2

I think you complicate your program unnecessarily with calls to functions that do not clarify the code, recover can be done in a simpler way, and personally I always look for the greatest possible simplicity. Particularly suspicious I find the function FILE * openFile (char * filename). This function theoretically returns an open file, specifically a ...


2

Mars is right, the code is too complex. Too much complexity around opening, closing, and testing for open files. It's understandable that when code is executed repeatedly, you'd want to create a function to put the repeating code in one place. You created two functions, one to create the filename and one to open the file. Since the filename function is ONLY ...


2

Effectively your algorithm is correct, but there is a small mess with the pointers, you declare a pointer to the buffer in which it will be written: uint8_t *buffer_ptr = malloc(FAT_BLOCK_SIZE); So, what is buffer_ptr ?, a pointer, the name itself is the pointer, since we have thus declared this variable. And what is & buffer_ptr ?, well it is a ...


2

This "argv[1]" is the string literal argv[1] (because of the "s), and no such file name exists.


2

It looks like gibberish because the code is printing it as if it were ASCII char data. In reality, it is literally raw digital data. It doesn't translate to ASCII codes or anything else. Instead, it represents either header data in a jpeg file or the digital representation of colors in pixels. It's really not printable. So, first of all, you'd need to ...


2

It's a problem with processing the EOF condition on the input file. The code is structured so that it reads in 512 bytes, copies them out to the output file, and then checks for EOF. In other words, "Ready, Fire, Aim!" Note that the EOF flag is not set until an attempt is made to read beyond the end of the file. When the last byte in the input ...


1

bmp.h doesn't exist in check50 for this assignment, so the file is never included. This leads to compile errors. You'll need to incorporate the definition of BYTE into recover.c, or use another type, such as uint8_t. If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)


1

The problem is due to a data overwrite bug. The problem lies in these two lines: char jpgName[4]; // array for 3 symbols with trailing 0 .... // give a name and write the 1st block sprintf(jpgName, "%03i.jpg", fileCounter); The full file name is 8 chars long (7 for the name and 1 for the \0) and is written to jpgName. Since only 4 chars ...


1

You write first sector twice for each file. Remove first fwrite(buffer, 512, 1, img); And I'd put another if (img != NULL) in front of the second fclose(img); in case the dump contains no JPEG file at all.


1

A loop is definitely the way to go, not if statements. Now, have you looked at the size of the file(s) produced? I suspect that the first file created is much larger than it should be - a significant percentage of the input file. Let's look at the code and see what it is really doing. The code searches for the first signature. Once found, it opens an ...


1

You have multiple fread, each reading 512 bytes, but not every read sector seems to be written even after opening a file. This means you're skipping some sectors. Instead of a do..while loop, use a regular while, and remove any fread in the body, keep only the one in the condition. This will take care of reading and checking for input file end at the same ...


1

Since it should persist over multiple iterations, move FILE* photo = NULL; above your loop. Otherwise you're creating a new variable each iteration and set it to NULL, which makes fwrite fail. Second segmentation fault when fclose(filename);. Replace it with something like if (a > 0) fclose(photo); Oh, and off by one. First file should be 000.jpg. Move ...


1

Also, newfile needs to contain the name of the file to be opened. It never has the filename assigned to it.


1

int p=0; char *newfile = malloc(sizeof(buffer)*p); You actually have zero bytes reserved with malloc


1

You have to check the first 4 bytes for every new JPEG and not just the first. Then if you have a new JPEG, you should open a new file, write the data to it. If the next block is not a new JPEG, then write the block to the same file. If it is a new JPEG, close the previous file and open a new one and write to it. Also, you aren't closing the files right now, ...


1

At first read PSET4 RECOVER Can't Open JPEGS, I Have Tried Everything Please HELP! about sizeof(buffer) Then, do something with the whole logic of your code. Write it in your language (english or whatever it is) and then try to implement step by step with C. For now, I am sorry, but it is a mess. Just look what you are doing: You read a block from card....


1

Hmmmm..... fwrite(&inptr, 512, 1, img); What's the name of your buffer? BTW, in case you were thinking about it, fwrite will not write directly from one file to another. It only writes from memory to a file. Because of that, it's actually reading 512 bytes from the pointer var's location in memory. Also, even if it did, the code above would ...


1

You should read 512 bytes, not 512 ints. A type holding a byte could be the BYTE alias, or unsigned char, or, my preference, uint8_t. And yes, a single fread in the loop head should be sufficient. You use malloc, but never check its return value. Please don't do that (although it's unlikely for malloc to ever return NULL, especially in this setting). You ...


1

Shouldn't your buffer be an array of 512 bytes? (unsigned chars)? You've declared an array of integers.


1

Most of the pieces are here, but this is a good example of overcomplicated code. Let's start with something simple. Look at this from the end of the code (comments removed): if (outfile == NULL) { continue; } else { fwrite(buffer, BLOCKOFBYTES, 1, outfile); } When an if statement is ...


1

I tested with your code and it's definitely correct, as @cliff has said in the commment. Do make sure the file you are opening actually has more than 512 bytes. Perhaps your rawfile has been corrupted?


1

[EDIT: Note: From year to year, the psets get redesigned and tests and data files can and do change. Some of this information may no longer be true as time passes. Keep this in mind while reading. Cliff B. 12/26/2019] First, understand that check50 uses a different input file than the one that is provided. (There's a history to that, but that's another ...


Only top voted, non community-wiki answers of a minimum length are eligible