5

I am currently trying to read 256 bytes from a binary file and not getting any output (or errors) when running my program. I am a little confused where I am going wrong on this. Attempting to read each byte as a char and store as a char array of length 256. I have reviewed similar questions on SO already and haven't had any luck so far. Simplified version of my code below:

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

int main(int argc, char *argv[]){
    FILE *binary = fopen(argv[1], "rb");
    char bytesFromBinary[256];

    fread(&bytesFromBinary, 1, 256, binary);
    printf("%s", bytesFromBinary);
    return 0;
}
5
  • 9
    You're trying to read binary and then print it using a string format specifier. What output do you expect if that binary data starts with a null byte or the bytes are all non-printable values? Or what happens if those bytes don't contain a null terminator to tell printf where it stops? Commented Apr 4, 2016 at 1:18
  • 1
    Iterating through your array and printing each value of the array as a number should help you see what is in the array because it will not interpret extended or restricted ASCII characters, but as integer values. Commented Apr 4, 2016 at 1:31
  • What are the actual contents of the file? Can you post a snippet? Commented Apr 4, 2016 at 1:37
  • It is just a .bin file. Cannot open and see anything meaningful even in notepad++ Commented Apr 4, 2016 at 1:39
  • 3
    Why do you expect printf to print something meaningful then? Commented Apr 4, 2016 at 1:57

3 Answers 3

6

A basic use of fread will check the return against the number of bytes expected to validate you read what you intended to read. Saving the return allows you to handle partial reads as well.

The following minimal example reads 16-bytes at a time from the file given as the first argument (or stdin by default if no file is given) into buf and then outputs each value to stdout in hex-format.

#include <stdio.h>

#define BUFSZ 16

int main (int argc, char **argv) {

    unsigned char buf[BUFSZ] = {0};
    size_t bytes = 0, i, readsz = sizeof buf;
    FILE *fp = argc > 1 ? fopen (argv[1], "rb") : stdin;

    if (!fp) {
        fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
        return 1;
    }

    /* read/output BUFSZ bytes at a time */
    while ((bytes = fread (buf, sizeof *buf, readsz, fp)) == readsz) {
        for (i = 0; i < readsz; i++)
            printf (" 0x%02x", buf[i]);
        putchar ('\n');
    }
    for (i = 0; i < bytes; i++) /* output final partial buf */
        printf (" 0x%02x", buf[i]);
    putchar ('\n');

    if (fp != stdin)
        fclose (fp);

    return 0;
}

(note: bytes == readsz only when the size parameter to fread is 1. The return is the number of items read and each item is only equal to 1 for char type values)

Example Use/Output

$ echo "A quick brown fox jumps over the lazy dog" | ./bin/fread_write_hex
 0x41 0x20 0x71 0x75 0x69 0x63 0x6b 0x20 0x62 0x72 0x6f 0x77 0x6e 0x20 0x66 0x6f
 0x78 0x20 0x6a 0x75 0x6d 0x70 0x73 0x20 0x6f 0x76 0x65 0x72 0x20 0x74 0x68 0x65
 0x20 0x6c 0x61 0x7a 0x79 0x20 0x64 0x6f 0x67 0x0a

Look over the example and let me know if you have any questions.

Sign up to request clarification or add additional context in comments.

Comments

0

You have not declared a long enough variable.

Your declaration char bytesFromBinary[256]; reserves 256 bytes, and fread fills all 256 bytes. There is no trailing '\0' and there is no space for it, so whatever happens to be next in memory gets overwritten/destroyed. That already will result in all kind of random errors and crashes.

Then, in printf, you try to print it, and the function will keep running through memory until it happens to encounter a '\0' to stop it, so if the program makes it there, you would get a printout of memory, maybe short, maybe thousands of (non-printable) characters long.

You need to declare the variable always one longer, to have space for the trailing '\0': char bytesFromBinary[257];. even better is to use sizeof(var)-1 in fread, or use a constant for the desired length and declare it with +1.

1 Comment

changed to bytesFromBinary[257] and same output (none)
-1

It fails because you are trying printing a block of bytes as a C-style string.

There are two kinds of files: binary file and text file. To read/write a file, you should open it in the corresponding mode.

If your file is created in this way:

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

int main(int argc, char *argv[])
{
    FILE *binary = fopen("file.txt", "wbx");
    if(!binary)
    {
        perror("fopen()");
        exit(EXIT_FAILURE);
    }
    char bytesToBinary[256] = ":-)";

    fwrite(bytesToBinary, 1, 256, binary);
    fclose(binary);
    return 0;
}

Your code should be successful.

9 Comments

i am opening in binary mode as it is a binary file. Not sure what you are saying to fix here
binary means 'non-printable characters'. If you try to print them anyway, you will get strange behavior.
The problem here is not that it's not opened in binary mode.
Also, there aren't two kinds of file, on any operating system I've encountered. Text files are files that happen to contain ASCII (or Unicode) characters, and binary files are files that don't.
@immibis If you write a C-style string to a binary file by fwrite(), and then read it out by fread(), that string will remain unchanged. Thus OP's code will work as he expect.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.