I am creating an archive program in C, and i want it to save files i provide, list and extract them.
I had many issues because i used a text file for saving, and it is not the best choice if i want to process binary files like music or photos, because when i extract them, they are not executed correctly (they are corrupted).
In order to solve this problem, i wanted to create a binary archive file.
Code for file writing (on extraction) is the following:
void scriviFile(const char * arrivo) //scrive i file creati in precedenza
{
FILE * partenza;
FILE * target;
int c;
int spazio = 'a';
int i = 0;
int pos;
char * path;
path = collegaSlash(getcwd(NULL, 0), nome);
partenza = fopen(path, "rb");
fseek(partenza, inizio, SEEK_SET);
target = fopen(arrivo, "wb"); //apro il file
if (target) { //se è aperto
while ((c = fgetc(partenza)) != EOF && ftell(partenza)<=fine-10) { //e il carattere preso non eccede la fine del file
fputc(c, target);
fputc(c, stdout);
pos = ftell(partenza);
if(pos==fine)
{
break;
}
//scrivo lo stesso carattere in out (file in uscita)
} //
fclose(target); //chiudo il file
fclose(partenza);
}
else
{
printf("errore di scrittura del file \n");
}
}
Since i need binary files to be extracted correctly, can i use code i wrote above, or do i have to change all fgetc()
and fputc()
functions with fread()
and fwrite()
?
Thanks
You're using fgetc()
and fputc()
as you can see from the man page descriptions these function:
fgetc() reads the next character from stream and returns it as an unsigned char cast to an int, or EOF on end of file or error.
fputc() writes the character c, cast to an unsigned char, to stream.
A character, in C, is defined by the standard to always be exactly 1 byte (8 bits), this means when you use fxxxc()
on a file you'll get 1 byte (that just happens to be a character in a text file).
If you extract and rebuild a binary file, byte by byte, you'll get an exact duplicate. So no, there is no issues with using fgetc()
and fputc()
on a binary file type. You can always prove this to yourself with a simple example program... for example:
int main()
{
FILE * fptr = fopen("small_pic.jpg", "rb"); // open existing binary picture
char buffer[10000] = {0}; // the pic is 6kb or so, so 10k bytes will hold it
FILE * fptr2 = fopen("new_small_pic.jpg", "wb"); // open a new binary file
// for our copy of the pic
unsigned long fileLen;
unsigned long counter;
fseek(fptr, 0, SEEK_END);
fileLen=ftell(fptr); // get the exact size of the pic
fseek(fptr, 0, SEEK_SET);
for(counter=0; counter<fileLen; counter++)
fputc(fgetc(fptr),fptr2); // read each byte of the small_pic.jpg and make
// a new pic from it
fclose(fptr);
fclose(fptr2);
return 0;
}
end result: we have two of the exact same images, because fgetc()
and fputc()
can be used on binary files.