Can i use fgetc() or fputc() in a binary file?

Andrea Gottardi picture Andrea Gottardi · May 10, 2013 · Viewed 12.2k times · Source

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

Answer

Mike picture Mike · May 10, 2013

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.