C Programming: how can I read and print bytes from a binary file?

I want to open a binary file to read the first byte of the file and finally print the hex value (in string format) in stdout (i.e. if the first byte is 03 hex, I want to print 0x03 for example). The output I get does not match what I know in my binary, so I'm wondering if anyone can help with this.

Here is the code:

#include <stdio.h> #include <fcntl.h> int main(int argc, char* argv[]) { int fd; char raw_buf[1],str_buf[1]; fd = open(argv[1],O_RDONLY|O_BINARY); /* Position at beginning */ lseek(fd,0,SEEK_SET); /* Read one byte */ read(fd,raw_buf,1); /* Convert to string format */ sprintf(str_buf,"0x%x",raw_buf); printf("str_buf= <%s>\n",str_buf); close (fd); return 0; } 

The program is compiled as follows:

gcc rd_byte.c -o rd_byte

and do the following:

rd_byte BINFILE.bin

Knowing that the sample binary used has 03 as its first byte, I get the output:

str_buf = <0x22cce3>

What do I expect str_buf = <0x03>

Where is the error in my code?

Thanks for any help.

+4
source share
5 answers

Less - more...

 #include <stdio.h> #include <fcntl.h> #include <unistd.h> int main(int argc, char* argv[]) { int fd; unsigned char c; /* needs error checking */ fd = open(argv[1], O_RDONLY); read(fd, &c, sizeof(c)); close(fd); printf("<0x%x>\n", c); return 0; } 
  • seek ing not required
  • if you want to read the byte use unsigned char
  • printf will make the format
+5
source

You print the value of the raw_buf pointer, not the memory in this place:

 sprintf(str_buf,"0x%x",raw_buf[0]); 

As Andreas said, str_buf also not large enough. But: there is no need for a second buffer, you can just call printf directly.

 printf("0x%x",raw_buf[0]); 
+7
source

I think that you are too complicated and use intolerable constructions where they really are not needed.

You should be able to:

 #include <stdio.h> int main(int argc, char** argv) { if (argc < 2) return 1; /* TODO: better error handling */ FILE* f = fopen(argv[1], "rb"); /* TODO: check f is not NULL */ /* Read one byte */ int first = fgetc(f); if (first != EOF) printf("first byte = %x\n", (unsigned)first); /* TODO else read failed, empty file?? */ fclose(f); return 0; } 
+4
source

str_buf has a maximum size of 1 ( char str_buf[1]; ), it must be at least 5 bytes long (4 for XxXX plus \ 0).

Also change

 sprintf(str_buf,"0x%x",raw_buf); 

to

 sprintf(str_buf,"0x%x",*raw_buf); 

otherwise, you will print the address of the raw_buf pointer instead of its value (which you will get by dereferencing the pointer).

Finally, make sure raw_buf is unsigned . The standard states that the meaning of characters (where not explicitly indicated) is determined by the implementation, i.e. Each implementation decides whether they should be signed or not. In practice, in most implementations they are signed by default unless you compile a specific flag. When working with bytes, always make sure that they are unsigned; otherwise, you will get unexpected results if you want to convert them to integers.

+2
source

Using the information from the various answers above (thanks everyone!), I would like to post this piece of code, which is an abridged version of what I finally used.

However, there is a difference between what the following code does and what was described in my original question: this code does not read the first byte of the binary file header as described initially, but instead reads the 11th and 12th bytes (offsets 10 and 11) the input binary file (.DBF file). The 11th and 12th bytes contain the length of the data record (this is what I really want to know) with the first least significant byte: for example, if the 11th and 12th bytes are relative: 0x06 0x08, then the length of the record data will be 0x0806 bytes or 2054 bytes in decimal

  #include <stdio.h> #include <fcntl.h> int main(int argc, char* argv[]) { int fd, dec; unsigned char c[1]; unsigned char hex_buf[6]; /* No error checking, etc. done here for brevity */ /* Open the file given as the input argument */ fd = open(argv[1], O_RDONLY); /* Position ourselves on the 11th byte aka offset 10 of the input file */ lseek(fd,10,SEEK_SET); /* read 2 bytes into memory location c */ read(fd, &c, 2*sizeof(c)); /* write the data at c to the buffer hex_buf in the required (reverse) byte order + formatted */ sprintf(hex_buf,"%.2x%.2x",c[1],c[0]); printf("Hexadecimal value:<0x%s>\n", hex_buf); /* copy the hex data in hex_buf to memory location dec, formatting it into decimal */ sscanf(hex_buf, "%x", &dec); printf("Answer: Size of a data record=<%u>\n", dec); return 0; 

}

0
source

All Articles