+6  A: 

You're printing the value of the pointer raw_buf, not the memory at that location:

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

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

printf("0x%x",raw_buf[0]);
Nick Meyer
i would prefer to use printf("0x%.02x",raw_buf[0]); so it prints the same size of every byte input
Douglas Gemignani
+2  A: 

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

Moreover, change

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

to

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

otherwise you'll print the address of the raw_buf pointer, instead of its value (that you obtain by dereferencing the pointer).

Finally, make sure both raw_buf is unsigned. The standard specified that the signness of chars (where not explicitly specified) is implementation defined, ie, every implementation decides whether they should be signed or not. In practice, on most implementations they are signed by default unless you're compiling with a particular flag. When dealing with bytes always make sure they are unsigned; otherwise you'll get surprising results should you want to convert them to integers.

Andreas Bonini
+4  A: 

I think that you are overcomplicating things and using non-portable constructs where they aren't really necessary.

You should be able to just do:

#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;
}
Charles Bailey
+3  A: 

Less is 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));
    printf("<0x%x>\n", c);
    return 0;
}
  1. seeking is not needed 2) if you
  2. want to read a byte use an unsigned
  3. char 3) printf will do the format
dtmilano
A: 

Using the information from the various responses above (thank you all!) I would like to post this piece of code which is a trimmed down version of what I finally used.

There is however a difference between what the following code does and what was described in my origal question : this code does not read the first byte of the binary file header as described originally, but instead reads the 11th and 12th bytes (offsets 10 & 11) of the input binary file (a .DBF file). The 11th and 12th bytes contain the length of a data record (this is what I want to know in fact) with the Least Significant Byte positioned first: for example, if the 11th and 12th bytes are respectivly : 0x06 0x08, then the length of a data record would be 0x0806 bytes, or 2054bytes 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;

}

Esquif