3

i'm a little puzzled about binary files and how to read from them, so if someone could help that would be great. i have a file that contains the following bits:

00000000000000000000000000000111 

(32 bits. i counted)

now i have written this code:

int main()
{
    FILE * f1;
    f1 = fopen("file2", "rb");
    int i = 0;
    fread(&i, sizeof(int), 1, f1);
    printf("%d", i);
    fclose(f1);
    return 0;

}

that prints me 808464432. why? shouldnt it print 7? thank you for reading.

mike
  • 767
  • 2
  • 10
  • 18
  • How can you check the content of the file? – Iharob Al Asimi Feb 19 '15 at 14:10
  • 2
    print out your `sizeof(int)`. you may be dealing with a 2byte int, which means you're reading two bytes worth of 0-bits, meaning your "int" will be `0`. And how did you count the bits? If your file is "binary", then it'd have a file size of 4 bytes. if it's text, then it'd be 32 bytes. – Marc B Feb 19 '15 at 14:11
  • my sizeof(int) is 4, and i am sorry that i mislead you, the output is 808464432, not 0. – mike Feb 19 '15 at 14:18
  • 3
    ...which means, Iharob's guess is correct and this file doesn't contain the _bits_ 0000...., but contains 0 characters (0x30 in ASCII), followed by some 1 characters. 808464432 = 0x30303030 – mafso Feb 19 '15 at 14:20
  • i see. so how do i create such a binary file? – mike Feb 19 '15 at 14:22
  • 1
    `fwrite(&i, sizeof i, 1, f1)` ;) Be aware, that these files are non-portable (you cannot write on one machine and read on another) and possibly non-consistent for code compiled with different compilers (if they are ABI-incompatible). – mafso Feb 19 '15 at 14:25
  • i understand now. thx! so how come i can write binary files only from that form? – mike Feb 19 '15 at 14:34
  • Doing that yourself depends on some factors and it might become tricky to enter those characters in a text editor (use a hex editor for that). With ASCII and a little-endian system, a file consisting of an alert (escape sequence '\a', ASCII 0x07) followed by three zero-bytes would do in this case. – mafso Feb 19 '15 at 19:06

2 Answers2

4

That is not a binary file, it's a text file, try this instead

#include <stdio.h>
#include <stdlib.h>

int main()
{
    FILE *file;
    int   value;
    char  text[33];
    char *endptr;

    file = fopen("file2", "r");
    if (file == NULL) /* check that the file was actually opened */
        return -1;
    if (fread(text, 1, sizeof(text) - 1, f1) != sizeof(text) - 1)
    {
        fclose(file);
        return -1;
    }
    text[32] = '\0';
    value    = strtol(text, &endptr, 2);
    if (*endptr == '\0')
        printf("%d", value);
    fclose(file);
    return 0;
}

To write a binary file you need this

#include <stdio.h>

void hexdump(const char *const filename)
{
    FILE         *file;
    unsigned char byte;


    file = fopen(filename, "rb");
    if (file == NULL)
        return;
    fprintf(stdout, "hexdump of `%s': ", filename);
    while (fread(&byte, 1, 1, file) == 1)
        fprintf(stdout, "0x%02x ", byte);
    fprintf(stdout, "\n");
}

int main()
{
    const char *filename;
    FILE       *file;
    int         value;

    filename = "file.bin";
    file     = fopen(filename, "wb");
    if (file == NULL)
        return -1;
    value = 7;
    if (fwrite(&value, sizeof(value), 1, file) != 1)
        fprintf(stderr, "error writing to binary file\n");
    fclose(file);

    /* check that the content of the file is not printable, i.e. not text */
    hexdump(filename);

    file = fopen(filename, "rb");
    if (file == NULL)
        return -1;
    value = 0;
    if (fread(&value, sizeof(value), 1, file) != 1)
        fprintf(stderr, "error writing to binary file\n");
    else
        fprintf(stdout, "The value read was %d\n", value);
    fclose(file);

    return 0;

}

as you will see from the example above, the stored data in file.bin is not in text format, you cannot inspect it with a text editor because the bytes 0x00 and 0x07 are not printable, in fact 0x00 is the nul byte which is used in c to mark the end of a string.

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
  • but according to this post, is not all files are binary, untill been told they are text? http://stackoverflow.com/questions/979816/whats-a-binary-file-and-how-do-i-create-one\ – mike Feb 19 '15 at 14:12
  • Because a binary file consinting of only text is equivalent to the corresponding text file, but if you store integers in a binary file, it's very unlikely that you will see the textual representation of the integer value, also `"rb"` AFAIK only does't deal with end of line character as `"r"` would. – Iharob Al Asimi Feb 19 '15 at 14:14
  • thank your time, but i'm a little confused. how do i create a binary file with 32 bits/ 4 bytes like i described then? – mike Feb 19 '15 at 14:17
  • @mike did this output `7`? – Iharob Al Asimi Feb 19 '15 at 14:21
  • @mike Oops, its `if (*endptr == '\0')` instead of `if (*endptr != '\0')`. I fixed it, it should print `7`. – Iharob Al Asimi Feb 19 '15 at 14:31
2

This is one way you can write and read to a binary file. you should know the difference between a binary and ASCII file, before reading from them. Read this once https://stackoverflow.com/a/28301127/3095460 and understand what is type of file you are reading using your code.

if you open a file in an editor and see 00000000000000000000000000000111 it does not mean its a binary file, most of the editor process files as ascii text file only. you need a binary editor to open a binary file and read meaningful data from them.

#include <stdio.h>

int main()
{
    FILE *Read_fptr  = NULL;
    FILE *Write_fptr = NULL;
    int   data       = 20;
    size_t nElement  = 1;

    if ( (Write_fptr = fopen("data.bin", "wb")) != NULL ) {
        if ( fwrite(data, nElement, sizeof data, Write_fptr) != sizeof data ) {
            fprintf(stderr,"Error: Writing to file\n");
            fclose(Write_fptr);
            return -1;
        }
    } else {
        fprintf(stderr,"Error: opening file for writing\n");
        return -1;
    }
    fclose(Write_fptr);
    data = 0;
    if ( (Read_fptr = fopen("data.bin", "rb")) != NULL ) {
        if ( fread(data, nElement, sizeof data, Read_fptr) != sizeof data) {
            if( !feof(Read_fptr) ) {
                fprintf(stderr,"Error: Reading from file\n");
                fclose(Read_fptr);
                return -1;
            }
        }
    } else {
        fprintf(stderr,"Error: opening file for reading\n");
        return -1;
    }
    fclose(Read_fptr);

    printf("%d\n",data);
    return 0;

}
Community
  • 1
  • 1
Sridhar Nagarajan
  • 1,085
  • 6
  • 14