fprintf() writes data in text format regardless to the mode I use in fopen() to open the file

Viewed 464

Trying to store an int in binary mode using fprintf() but no matter which mode I specify in fopen() it is writing int value only in text format. On the other hand when i use fwrite in place of fprintf it stores the int in binary format. So can we use fprintf in binary mode?

#include <stdio.h>

int main()
{
    FILE *fp;
    fp = fopen("abc.bin", "wb");
    int num = 69;
    fprintf(fp, "%d", num);
    fclose(fp);
    return 0;
}

Also if we talk about other I/O functions which of them will work perfectly with binary mode? Is there anything officially documented about such behaviors ?

I am working on windows platform under mingw.

1 Answers

fprintf() is meant to convert int arguments to human readable format. To store binary data to your file, you must indeed open it in binary mode with "wb" or "ab" and you can use fwrite or putc:

int n = 1234;
if (fwrite(&n, sizeof(n), 1, fp) == 1) {
    // n was successfully written to fp
}

fwrite stores the int value using the representation and byte order in use in the running system. If the file can be transferred to a different system to be read there, you must specify the byte order and representation used in the file and implement the read and write functions in a portable manner:

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

int write_int32_le(int n, FILE *fp) {
    /* write the int as a 4 byte little endian two's complement representation */
    uint32_t u32 = n;
    int res = 4;
    for (int i = 0; i < 4; i++) {
        if (putc(u32 & 255, fp) == EOF)
            res = EOF;
        u32 >>= 8;
    }
    return res;
}

int read_int32_le(FILE *fp) {
    /* write the int as a 4 byte little endian two's complement representation */
    uint32_t u32 = 0;
    for (int i = 0; i < 4; i++) {
        int c = getc(fp);
        if (c == EOF)
            return EOF;
        u32 |= (uint32_t)c << (i << 3);
    }
    return (int)u32;
}

Other representations could be used in your binary file, such as big-endian or LEB128

Related