I have completed the pset, and am happy with my code and how it works. But had some design questions so that I know for future programs what and why to use.
I understand that it does not really matter for the scale of this program. I will not post the entire code here since that is against the policy but can send a pastebin in private if you'd like.
No lacanian or freudian responses re:sexy code, it is admittedly a linkbait title.
What are the proper ways of buffering partial contents of a file in a way that one can compare the contents? In my Tarzan C, I used the following because char would store the ASCII codes for the hexadecimal digits and I wasn't sure if I could compare those. Should I have used plain int? How does one compare hexadecimal strings with that? I used uint8_t because that was storing what I was looking for when I printed in gdb.
comparing file contents
In comparing the beginning of the buffer with (0xff 0xd8 0xff 0xe0 || 0xff 0xd8 0xff 0xe0), I employed the good old randomly accessible char array and referenced characters by position individually. Is there a more elegant way of doing this? I know you can use memcmp(string.h) but that would require the declarations of two more arrays and would look just as, if not more convoluted, given that the program only looks for two non changing hex strings. Here is what I used. Should I have typecast or something instead?
if ( buffer == 0xFF && buffer == 0xD8 && buffer == 0xFF && ( buffer == 0xE0 || buffer == 0xE1 ) )
pointer declarations and sprintf
As per Kareem's answer, I had just carried over an earlier troubleshooting attempt of an earlier design problem, thinking that sprintf was a function and therefore could not accept variables, the following is perfectly fine
int file_counter = 0; sprintf (outptr_name,"%.3d.jpg", pfile_counter++);
To keep track of the file number, I used a pointer. Two questions here, should I have just malloc() in declaring the int *pfile_counter instead of declaring an int first and pointing to the address of that int? Or should I have just used a global variable instead of a pointer?
int file_counter = 0; int *pfile_counter = &file_counter;
Here is how I am using the counter, is the sprintf redundant? could I have used lower level code to set the file name?
sprintf (outptr_name,"%.3d.jpg", (*pfile_counter)++);
feof order of operation
Finally, I run the main reading/writing bits in a forever loop that breaks out when fread sets feof. It does not matter particularly for this pset because of the generous padding at the end of the last file but I'm a bit confused about the order of things in utilizing feof.
When fread() reads the end of the file, and say it is not 512 bytes but instead 500, and happens to contain data that I want to writeout, does it read both the 500 bytes and the feof, or does it read the 500 bytes, and returns feof the next time I run fread()?
here is how I declared fread(), I found that if you don't ask for 512 elements but one element of size 512, it will return 0 even if you have say 500 bytes left before EOF
fread(&buffer, sizeof(uint8_t), 512, file);
In that, should I be designing the loop so that it iterates one last time after detecting feof, writing out the buffer that reached the end of the file? Or should the loop quit before writing the last read buffer because it only contains feof? From what I gather, it would return the number of data elements, so 512 until the end, 500 at the end (and again let's say the last block is 500 bytes though it can't be in FAT.), and 0 once you try again, which sets feof(). Diagrammed below is what I am guessing to happen at the end of the file, including the last full block.
reads 512 elements | reads 500 as there is no more | reads no elements returns 512 | returns 500 | returns 0; sets feof()
people seem to keep referring to the cprogramming.com article but that example only fails because he/she is reading first, and processing the buffer in the rest of the loop. One could easily employ fread at the end as below, and skip fwrite if reading has not begun yet (ie.first iteration)
With the assumption above, the following pseudocode would work in itself because with the read and write reversed, buffer would not be processed once feof is true ( i dismissed the rest for brevity, assume we are handling openings and closing elsewhere )
Phew, that was a bunch of questions.. Thank you very much. I exhausted my capacity to understand the books on these, I only started to course 8-9 days ago and never saw C before.