Thread: Convert binary data to string

  1. #1
    Registered User
    Join Date
    Aug 2010
    Posts
    63

    Convert binary data to string

    Hi all,

    I have a binary file (file.bin) and i want to display it exactly like the command "od -x" do, for example:
    Code:
     od -x file.bin
    give me this output :
    Code:
    4bff    4200    331f    0000    0051    fff1    ffff    4bff
    4200    001f    0811    0000    1000    5033    0214    0912
    4120    1450    1202    2009    5047    0214    0912    0020
    0000    0000    0000    0000    0006    0000    0000    ff00
    I want to store all this output in a char buffer to do some other stuff...
    Is there a simple manner to do that? Thanks for your help.

    Many regards.

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Search the board -- there are tons of posts on this topic.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User
    Join Date
    May 2010
    Posts
    4,478
    If you are on Linux then you could use popen to pipe the output of od -x file.bin into your program.

  4. #4
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    thanks guys for your answers, i don't want to use the "od -x" command, i want to do the same thing without using it.

    Thanks.

  5. #5
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    If the binary data has it's "rows" separated by a newline, then fgets() would be an obvious choice.

    If the space between the data is in the file already, then you're ready for output as you wish. If not, a simple "output 1 data item, output N number of spaces (or tabs)", logic is needed.

    Give it a try, and come back if you get stuck and post your code so we have something specific to refer to.

  6. #6
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Thanks Adak for the reply, my code is :


    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main ()
    {
    	FILE *fd; 
    	char line[BUFSIZ]; 
    	int i;
    	
    	if (NULL == (fd = fopen ("input.bin", "r")))
    	{
    		fprintf (stderr, "Can't open file\n"); 
    		exit (EXIT_FAILURE);
    	} 
    	while (fgets (line, BUFSIZ, fd))
    	{
    		for(i = 0;i < BUFSIZ;++i)
    		     printf("%.2X ", (int)line[i]);
    	}
    	 	if (!feof(fd))
    	{
    		fprintf (stderr, "Raed error\n"); 
    		exit (EXIT_FAILURE);
    	} 
    	fclose (fd);
    	printf ("\n");
    	
    	return 0;
    }
    And the input.bin (the binary file) is : (od -x input.bin)

    Code:
    0000000      0219    0912    4820    1905    1202    2009    0000    0000
    0000020      0003    0000    0000    0003    0000    0000    0000    0000
    0000040      ff01    ffff    ffff    ffff    ffff    ffff    ffff    05ff
    0000060      0505    0605    2605    6364    f246    ffff    ffff    ffff
    0000100      00ff    4132    02bf    0300    0010    0001    0000    ffff
    0000120      ffff    ffff    ffff    ffff    ffff    ffff    ffff    ffff
    0000140      0000    0000    0000    0000    0000    0000    0000    0000
    0000160      00ff    0000    ffff    ffff    ffff    ffff    ffff    ffff
    0000200      00ff    05ff    08ff    01f0    08ff    01f0    ffff    ffff
    0000220      ffff    ffff    02ff    0533    0219    0912    ff20    5343
    0000240      5049    3230    2020    ffff    ffff    ffff    ffff    0506
    0000260      5717    0801    8000    f300    ffff    ffff    0000    00db
    0000300      9512    0020    0000    60a3    4132    02bf    3300    0000
    0000320      0051    fff1    ffff    00ff    0000    0505    7133    7293
    0000340      f073    ffff    ffff    ffff    0506    6426    4663    fff2
    0000360      ffff    ffff    ffff    0401    ffff    0000    0011    0000
    0000400      3400    1905    1202    2009    0544    0219    0912    4820
    0000420      1905    1202    2009    0000    0000    0000    0003    0000
    0000440      0000    0000    ff00    0300    0000    0000    0000    ff00
    0000460      ffff    ffff    ffff    ffff    ffff    ffff    ffff    00ff
    0000500      0534    0219    0912    3220    bf41    0002    0001    0000
    0000520      ffff    ffff    ffff    ffff    ffff    ffff    ffff    0000
    0000540      ff00    ffff    ffff    ffff    ffff    ffff    ffff    33ff
    0000560      1905    1202    2009    ffff    ffff    0506    5717    0801
    0000600      8000    f300    ffff    ffff    ffff    ffff    ffff    ffff
    0000620      5343    5049    3230    2020    49ff    0101    2098    0000
    0000640      1d00    3298    c041    0002    0033    5100    f100    ffff
    0000660      ffff    0000    4200    2117    0100    1400    53f0    6228
    0000700      2530    6841    33f0    9371    7372    fff0    ffff    00ff
    0000720      ff07    ffff    ffff    ffff    ffff    ffff    ffff    ffff
    0000740      06ff    5371    0520    fff8    ffff    ffff    ffff    ffff
    0000760      1004    0537    8052    ffff    ffff    ffff    4bff    4300
    0001000      331f    0000    0051    fff1    ffff    4bff    4300    011f
    0001020      ff04    00ff    0011    0000    ff00    2430    1912    1202
    0001040      2009    1235    0219    0912    4420    1912    1202    2009
    0001060      0000    0000    0003    0000    0000    0009    0000    0000
    0001100      0000    0000    ff01    ffff    ffff    ffff    ffff    ffff
    0001120      ffff    05ff    0505    0605    7105    2053    f805    ffff
    0001140      ffff    ffff    00ff    4132    02c0    0300    0010    0001
    0001160      0000    ffff    ffff    ffff    ffff    ffff    ffff    ffff
    0001200      ffff    ffff    0000    0000    0000    0000    0000    0000
    0001220      0000    0000    00ff    0000    ffff    ffff    ffff    ffff
    0001240      ffff    ffff    00ff    05ff    08ff    01f0    08ff    01f0
    0001260      ffff    ffff    ffff    ffff    02ff    1223    0219    0912
    0001300      ff20    5343    5049    3230    2020    ffff    ffff    ffff
    0001320      ffff    0506    5717    0801    8000    f300    ffff    ffff
    0001340      0000    00db    9912    0020    0000    606b    4132    02c0
    0001360      3300    0000    0051    fff1    ffff    00ff    0000    0505
    0001400      7133    7293    f073    ffff    ffff    ffff    0506    5371
    0001420      0520    fff8    ffff    ffff    ffff    0401    ffff    0000
    0001440      0011    0000    2400    1912    1202    2009    1235    0219
    0001460      0912    4420    1912    1202    2009    0000    0000    0000
    0001500      0009    0000    0000    0000    ff00    0900    0000    0000
    0001520      0000    ff00    ffff    ffff    ffff    ffff    ffff    ffff
    0001540      ffff    00ff    1224    0219    0912    3220    c041    0002
    0001560      0001    0000    ffff    ffff    ffff    ffff    ffff    ffff
    0001600      ffff    0000    ff00    ffff    ffff    ffff    ffff    ffff
    if you run the program the out you get is not the same as od -x input.bin.

    Thanks.

  7. #7
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    'fgets' is for character-based files. You need to open the file in binary mode and then read in the data with fgetc, fread, or similar.
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  8. #8
    Registered User
    Join Date
    Oct 2008
    Location
    TX
    Posts
    2,059
    Read input file a char at a time with fgetc(), and format the output i.e. adjacent bytes (not) separated by whitespace if byte count modulo 2 (does not) equals zero.

  9. #9
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by Adak View Post
    If the binary data has it's "rows" separated by a newline, then fgets() would be an obvious choice.

    If the space between the data is in the file already, then you're ready for output as you wish. If not, a simple "output 1 data item, output N number of spaces (or tabs)", logic is needed.

    Give it a try, and come back if you get stuck and post your code so we have something specific to refer to.
    I think you misunderstood what the OP said. The input file is not text that contains hex strings, but an actual binary file.

    The "od" command outputs the addresses as octal numbers, which IMO is not very practical. You can easily change that to hex by changing "%08o" to "%08X" though.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int main () {
        FILE *in;
        unsigned int i=0;
        unsigned short val=0;
    
        in = fopen("main.c", "r");
    
        if(in == NULL) {
            fprintf (stderr, "Can't open file.\n");
            return EXIT_FAILURE;
        }
    
        while(fread(&val, 1, sizeof(unsigned short), in)) {
            if(i%8 == 0) {
                printf("\n%08o      ", i*sizeof(unsigned short));
            }
    
            printf("%04X    ", val);
    
            val=0;
            i++;
        }
    
        if(!feof(in)) {
            fprintf(stderr, "Read error.\n");
            fclose(in);
            return EXIT_FAILURE;
        }
    
        fclose(in);
        printf("\n");
    
        return EXIT_SUCCESS;
    }
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  10. #10
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Thanks maxorator, your program seems to be what i need, i got this warning :

    Code:
    warning: format ‘%08o’ expects type ‘unsigned int’, but argument 2 has type ‘long unsigned int’
    Thanks for your good explanation of how "od" works. Great answer .

    Many regards.

  11. #11
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    When you print long integers, signed or unsigned, in any base, prefix the base with l (L) and the warning goes away.

  12. #12
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Thanks whiteflags .

    Regards.

  13. #13
    Registered User
    Join Date
    Aug 2010
    Posts
    231
    It cant work.
    "rb" for fopen is needed.
    "%04x" not "%04X" is needed.
    The closing feof is redundant.
    fread must test for 2 (numblocks) not for !=0.

  14. #14
    Reverse Engineer maxorator's Avatar
    Join Date
    Aug 2005
    Location
    Estonia
    Posts
    2,318
    Quote Originally Posted by BillyTKid View Post
    It cant work.
    "rb" for fopen is needed.
    It's recommended to use for portability but won't usually change anything (at least on an UNIX-based OS which the OP seems to be using). I don't usually use the C standard library to mess with binary files so I forgot to add that.
    Quote Originally Posted by BillyTKid View Post
    "%04x" not "%04X" is needed.
    Whether I like hex with upper or lower case letters is completely up to me. I don't think there is a standard out there that would say only lower case hex letters are allowed.
    Quote Originally Posted by BillyTKid View Post
    The closing feof is redundant.
    It's not. It checks whether reading ended because of end of file or because of an error.
    Quote Originally Posted by BillyTKid View Post
    fread must test for 2 (numblocks) not for !=0.
    In that case it would strip the last partial block if the number of bytes in the file is not aligned to 2 bytes. Since fread always returns 0 on failure, this is a totally valid check to see whether any bytes were read.
    Last edited by maxorator; 08-24-2010 at 05:14 PM.
    "The Internet treats censorship as damage and routes around it." - John Gilmore

  15. #15
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    In that case it would strip the last partial block if the number of bytes in the file is not aligned to 2 bytes. Since fread always returns 0 on failure, this is a totally valid check to see whether any bytes were read.
    If that is the behavior you want, shouldn't you reverse the `1' and `sizeof(unsigned short)'?

    Actually, you should reverse them anyway.

    Soma

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Convert binary to decimal string
    By Devils Child in forum C# Programming
    Replies: 9
    Last Post: 01-26-2010, 07:37 AM
  2. Unable to compare string with 'getter' returned string.
    By Swerve in forum C++ Programming
    Replies: 2
    Last Post: 10-30-2009, 05:56 PM
  3. how to convert char string to user defined data type
    By prdeepss in forum C Programming
    Replies: 5
    Last Post: 08-02-2009, 09:59 AM
  4. Lame null append cause buffer to crash
    By cmoo in forum C Programming
    Replies: 8
    Last Post: 12-29-2008, 03:27 AM
  5. Binary Tree, couple questions
    By scoobasean in forum C Programming
    Replies: 3
    Last Post: 03-12-2005, 09:09 PM