Thread: binary file again

  1. #31
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Code:
    What kind of parsing stuff do you want to do? I have drafted (but not tested) code which will read the binary file into a linked list of lines that are the equivalent of the output of the "od -x" command.
    Thanks pheininger, you can post your code .

    Regards.

  2. #32
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Quote Originally Posted by Adak View Post
    You don't - I wanted it so I could check that the binary input and output was correct, by checking it with fc.

    You can delete that part, or save it to another file, or whatever you want.
    One of the problems i have with your code is that i want the hex dump 4 chars at one time, like this:

    Code:
    0000000      ff07    ffff    ffff    ffff    ffff    ffff    ffff    ffff
    0000020      06ff    1016    0740    fff3    ffff    ffff    ffff    ffff
    0000040      6004    0101    3074    ffff    ffff    ffff    4bff    4200
    0000060      331f    0000    0051    fff1    ffff    4bff    4200    011f
    0000100      ff04    00ff    0011    0000    ff00    1610    1939    1202
    Thanks.

    Regards.

  3. #33
    C lover
    Join Date
    Oct 2007
    Location
    Virginia
    Posts
    266
    Quote Originally Posted by jean.yves View Post
    One of the problems i have with your code is that i want the hex dump 4 chars at one time, like this:

    Code:
    0000000      ff07    ffff    ffff    ffff    ffff    ffff    ffff    ffff
    0000020      06ff    1016    0740    fff3    ffff    ffff    ffff    ffff
    0000040      6004    0101    3074    ffff    ffff    ffff    4bff    4200
    0000060      331f    0000    0051    fff1    ffff    4bff    4200    011f
    0000100      ff04    00ff    0011    0000    ff00    1610    1939    1202
    Thanks.

    Regards.
    I don't think the value will be 4 characters long if the value isn't large enough -by default. They are still the same numbers.

  4. #34
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Quote Originally Posted by Syscal View Post
    I don't think the value will be 4 characters long if the value isn't large enough -by default. They are still the same numbers.
    Totally agree with you, but i mean i want to bufferize the data exactly like what they appear with an hex dump tool (example with od -x).

    Regards.

  5. #35
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    Change this line of code:
    Code:
    printf("%x\t", buff[j]);
    to

    Code:
    printf("%04x\t", buff[j]);
    to adjust that.

  6. #36
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Quote Originally Posted by Adak View Post
    Change this line of code:
    Code:
    printf("%x\t", buff[j]);
    to

    Code:
    printf("%04x\t", buff[j]);
    to adjust that.
    I did that but i got a different display than "od -x", please try it and compare the output of the program and the output with an hex dump tool to see the problem.

    Regards.

  7. #37
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    I don't have a hex dump tool (I'm on Windows). I have a hex editor, but it shows different output than your hex dump tool.

    What's different, aside from the numbering along the left margin, for the dump tool?

  8. #38
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Quote Originally Posted by Adak View Post
    I don't have a hex dump tool (I'm on Windows). I have a hex editor, but it shows different output than your hex dump tool.

    What's different, aside from the numbering along the left margin, for the dump tool?
    You can see the output here:

    exec-snapshot.png - 4shared.com - photo sharing - download image

    On the left the hex dump tool, on the right our program.
    and my program is :
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    long filesize(FILE *fp); 
    
    int main(int argc, char **argv) {
      int j, n;
      long num, i;
      FILE *fp;
      char *buff;
      char *buff2;
    
      fp=fopen(argv[1], "rb");  
    
      if(fp==NULL) {
        printf("Error opening the file");
        return 1;
      }
    
      printf("\n\n");
      num=filesize(fp);
      //printf("Filesize of file_data is %ld bytes\n", num);
    
      buff=malloc(num); 
      buff2=malloc(num);
        
      if(buff==NULL) {
        printf("Error allocating memory");
        return 1;
      }
    
      n = fread(buff, num, 1, fp);
      if(n==0) {
        printf("Error reading the file");
        return 1;
      }
    
      printf("\n");
      for(j=0;j<num;j++) {
        if(j % 8==0) {
          printf("\n\t");
        }
        sprintf(buff2+j,"%x",buff[j]);
        printf("%04x\t", buff[j]);
      }
    
      /* just shows another way of printing out 
      the data - many char's are unprintable */
      /* 
      for(i=0;i<num;i++) {
        fputc(buff[i], stdout);
        if(i % 4 == 0 && i) 
          printf("   ");
      }  
      */
    
      fclose(fp);
    
      /*fp=fopen("copy1", "wb");
      if(fp==NULL) {
        printf("Error opening copy1 file");
        return 1;
      }
      fwrite(buff, num, 1, fp);
      fclose(fp);
      free(buff);
      free(buff2);
    
      printf("\n\n\t\t\t     press enter when ready");
      
      i = getchar(); 
      ++i;*/
      
      printf("\n");
    
      return 0;
    }
    
    long filesize(FILE *stream) {
       long curpos, length;
    
       curpos = ftell(stream);
       fseek(stream, 0L, SEEK_END);
       length = ftell(stream);
       fseek(stream, curpos, SEEK_SET);
       return length;
    }
    Regards.

  9. #39
    Registered User
    Join Date
    Sep 2006
    Posts
    8,868
    it's your display window - I'm using a console text window, 80 char's wide, with tabs every 8 or 10 char's across the width of the screen.

    Let me make an adjustment to it.

    Change the print line of code to:
    Code:
    printf("%04x    ", buff[j]);
    Last edited by Adak; 09-01-2010 at 10:56 AM.

  10. #40
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by jean.yves View Post
    "... I have drafted (but not tested) code which will read the binary file into a linked list of lines that are the equivalent of the output of the "od -x" command."

    Thanks pheininger, you can post your code .

    Regards.
    When you have it as ASCII characters 4 at a time, what are you going to do next with the data?

    Do you want the whitespace between them?

    Do you want the address printed every 8 16-words? If so, how do you want it separated from the file data?

    It appears that your processor is little endian. So do you want the bytes in hex or the 16-bit words in hex or in 32-bit words in hex?

    Do you understand how to manipulate your program in message 1 and 3 to print the data in hexadecimal instead of a string? (Hint: Use the %0x or %0X format in the printf (or fprintf or sprintf) statement.)

    I am reluctant at this point to post my draft code because:

    1) It is untested.
    2) Except for the code you gave in messages 1 and 3, you have not posted any revisions. There is a homework policy in this forum. My code would take you from almost no code to a nearly complete solution (unless of course I have a nasty subtle bug in it that I have not spotted). If you want more help, please show that you can use sprintf( ) into a buffer in hexadecimal format. Or ask specific questions about sprintf( ) and the hexadecimal format conversions.

    OK. Here is some partially tested code that does what you probably want but is does NOT do it like the "od -x" command. The following is NOT the code I drafted earlier. It is much closer to the code in messages 1 and 3. Since it is NOT extensively tested, use at your own risk and review comments would be appreciated.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define FILE_BLOCK 256u
    #define HEX_CHAR_PER_BYTE 2u
    
    int
    main (int argc, char **argv)
    {
       FILE *          in;
       size_t         wordidx;
       size_t         words_read;
       unsigned short filebuff[FILE_BLOCK];
       char           convbuff[FILE_BLOCK*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE+1];
    
       in = fopen(argv[1], "rb");
    
       if(in == NULL) {
           fprintf (stderr, "Can't open file.\n");
           return EXIT_FAILURE;
       }
    
       while ((words_read = fread(filebuff, sizeof(filebuff[0]), FILE_BLOCK, in)) > 0 ) {
           for ( wordidx = 0; wordidx < words_read ; wordidx++)
               sprintf(
                  &convbuff[wordidx*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE], 
                  "%04X", 
                  filebuff[wordidx]
               );
           /* process each convbuff here. */
       }          
    
       fclose(in);
    
       return 0;
    }
    Warnings:
    This was written assuming CHAR_BITS is 8 and sizeof(unsigned short) is 2.
    If an implementation uses a stack for its automatic variables, this implementation will require more than 512+1024+4+4 and one FILE * bytes on the stack. Make sure you configure your environment for enough stack.
    The place I am most likely to have errored is in the %04X format conversion specification. Of course, there are plenty of other places where I could have errored.
    Last edited by pheininger; 09-01-2010 at 12:17 PM. Reason: Added space for nul terminator in convbuff, corrected fread parameters and parens, and removed corresponding warning.

  11. #41
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Quote Originally Posted by pheininger View Post
    When you have it as ASCII characters 4 at a time, what are you going to do next with the data?

    Do you want the whitespace between them?

    Do you want the address printed every 8 16-words? If so, how do you want it separated from the file data?

    It appears that your processor is little endian. So do you want the bytes in hex or the 16-bit words in hex or in 32-bit words in hex?

    Do you understand how to manipulate your program in message 1 and 3 to print the data in hexadecimal instead of a string? (Hint: Use the %0x or %0X format in the printf (or fprintf or sprintf) statement.)

    I am reluctant at this point to post my draft code because:

    1) It is untested.
    2) Except for the code you gave in messages 1 and 3, you have not posted any revisions. There is a homework policy in this forum. My code would take you from almost no code to a nearly complete solution (unless of course I have a nasty subtle bug in it that I have not spotted). If you want more help, please show that you can use sprintf( ) into a buffer in hexadecimal format. Or ask specific questions about sprintf( ) and the hexadecimal format conversions.

    OK. Here is some partially tested code that does what you probably want but is does NOT do it like the "od -x" command. The following is NOT the code I drafted earlier. It is much closer to the code in messages 1 and 3. Since it is NOT extensively tested, use at your own risk and review comments would be appreciated.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define FILE_BLOCK 256u
    #define HEX_CHAR_PER_BYTE 2u
    
    int
    main (int argc, char **argv)
    {
       FILE *          in;
       size_t         wordidx;
       size_t         words_read;
       unsigned short filebuff[FILE_BLOCK];
       char           convbuff[FILE_BLOCK*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE+1];
    
       in = fopen(argv[1], "rb");
    
       if(in == NULL) {
           fprintf (stderr, "Can't open file.\n");
           return EXIT_FAILURE;
       }
    
       while ((words_read = fread(filebuff, sizeof(filebuff[0]), FILE_BLOCK, in)) > 0 ) {
           for ( wordidx = 0; wordidx < words_read ; wordidx++)
               sprintf(
                  &convbuff[wordidx*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE], 
                  "%04X", 
                  filebuff[wordidx]
               );
           /* process each convbuff here. */
       }          
    
       fclose(in);
    
       return 0;
    }
    Warnings:
    This was written assuming CHAR_BITS is 8 and sizeof(unsigned short) is 2.
    If an implementation uses a stack for its automatic variables, this implementation will require more than 512+1024+4+4 and one FILE * bytes on the stack. Make sure you configure your environment for enough stack.
    The place I am most likely to have errored is in the %04X format conversion specification. Of course, there are plenty of other places where I could have errored.
    Great code pheininger, thanks,

    I modify your code to see if it's ok for my problem :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define FILE_BLOCK 512u
    #define HEX_CHAR_PER_BYTE 2u
    
    int
    main (int argc, char **argv)
    {
       FILE *          in;
       size_t         wordidx;
       size_t         words_read;
       unsigned short filebuff[FILE_BLOCK];
       char           convbuff[FILE_BLOCK*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE];
       int			  i;
       char			  my_len[5];
    
       in = fopen(argv[1], "rb");
    
       if(in == NULL) {
           fprintf (stderr, "Can't open file.\n");
           return EXIT_FAILURE;
       }
    
       while ((words_read = fread(filebuff, FILE_BLOCK, sizeof(filebuff[0]), in) ) > 0 ) {
           for ( wordidx = 0; wordidx < words_read ; wordidx++)
               sprintf(
                  &convbuff[wordidx*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE], 
                  "%04X", 
                  filebuff[wordidx]
               );
    	for(i = 0; i < 4; i++)
    		my_len[i] = convbuff[i];
    	printf("%s\n", my_len);
       }          
    
       fclose(in);
    
       return 0;
    }
    and when i run the program with file_data (which is 4k, so 8 blocks of 512 each), i got just (4 blocks instead of 8):


    Code:
    $ ./a.out file_data 
    FF07
    FFFF
    3220
    1200
    Thanks.

  12. #42
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by jean.yves View Post
    Great code pheininger, thanks,

    I modify your code to see if it's ok for my problem :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define FILE_BLOCK 512u
    #define HEX_CHAR_PER_BYTE 2u
    
    int
    main (int argc, char **argv)
    {
       FILE *          in;
       size_t         wordidx;
       size_t         words_read;
       unsigned short filebuff[FILE_BLOCK];
       char           convbuff[FILE_BLOCK*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE];
       int			  i;
       char			  my_len[5];
    
       in = fopen(argv[1], "rb");
    
       if(in == NULL) {
           fprintf (stderr, "Can't open file.\n");
           return EXIT_FAILURE;
       }
    
       while ((words_read = fread(filebuff, FILE_BLOCK, sizeof(filebuff[0]), in) ) > 0 ) {
           for ( wordidx = 0; wordidx < words_read ; wordidx++)
               sprintf(
                  &convbuff[wordidx*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE], 
                  "%04X", 
                  filebuff[wordidx]
               );
    	for(i = 0; i < 4; i++)
    		my_len[i] = convbuff[i];
    	printf("%s\n", my_len);
       }          
    
       fclose(in);
    
       return 0;
    }
    and when i run the program with file_data (which is 4k, so 8 blocks of 512 each), i got just (4 blocks instead of 8):
    Because you changed FILE_BLOCK from 256u unsigned shorts (or 512 bytes) to 512u unsigned shorts (or 1024 bytes). The reason I used unsigned short is because you wanted it to match the output of "od -x" where the output is in 16-bit words. This is important because you have a little endian machine. The first two bytes of your sample file are 0x07 and 0xFF in that order for a 16-bit word with the value 0xFF07. Notice that the bytes reversed order.

    If you want FILE_BLOCK to be the actual block size in bytes, then the code could be changed to:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    #define FILE_BLOCK 512u
    #define HEX_CHAR_PER_BYTE 2u
    
    int
    main (int argc, char **argv)
    {
       FILE *          in;
       size_t         wordidx;
       size_t         words_read;
       unsigned short filebuff[FILE_BLOCK/sizeof(unsigned short)];
       char           convbuff[FILE_BLOCK*HEX_CHAR_PER_BYTE+1];
    
       in = fopen(argv[1], "rb");
    
       if(in == NULL) {
           fprintf (stderr, "Can't open file.\n");
           return EXIT_FAILURE;
       }
    
       while ((words_read = fread(filebuff, FILE_BLOCK/sizeof(filebuff[0]), sizeof(filebuff[0]), in) ) > 0 ) {
           for ( wordidx = 0; wordidx < words_read ; wordidx++)
               sprintf(
                  &convbuff[wordidx*sizeof(filebuff[0])*HEX_CHAR_PER_BYTE], 
                  "%04X", 
                  filebuff[wordidx]
               );
           /* process each convbuff here */
       }          
    
       fclose(in);
    
       return 0;
    }
    If you want the bytes in actual file order, change FILE_BLOCK to 512u and the type of filebuff to unsigned char in the original code.

    By the way, how does the my_len[ ] string become nul ('\0') terminated in your code before the printf( )?
    Last edited by pheininger; 09-01-2010 at 04:38 PM. Reason: Added question about my_len[ ] terminator.

  13. #43
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    if you want the bytes in actual file order, change FILE_BLOCK to 512u and the type of filebuff to unsigned char in the original code.
    what did you mean?

    Can you give me the output of your program because, it seems that the changes you add, didn't change anything.

    Thanks.

  14. #44
    Registered User
    Join Date
    Jun 2010
    Location
    Michigan, USA
    Posts
    143
    Quote Originally Posted by jean.yves View Post
    what did you mean?

    Can you give me the output of your program because, it seems that the changes you add, didn't change anything.

    Thanks.
    I have not been running each version.

    What I am expecting is that, on a little endian machine, if you use unsigned short version, the my_len[ ] display will look like FF07 and, if you use unsigned char version, the display will look like 07FF. On a big endian machine, they will both display 07FF.

    Is that clear?

  15. #45
    Registered User
    Join Date
    Aug 2010
    Posts
    63
    Quote Originally Posted by pheininger View Post
    I have not been running each version.

    What I am expecting is that, on a little endian machine, if you use unsigned short version, the my_len[ ] display will look like FF07 and, if you use unsigned char version, the display will look like 07FF. On a big endian machine, they will both display 07FF.

    Is that clear?
    Thanks for the program i think i can do some intresting stuff with your code .

    Regards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can you help me about tolower() in file
    By nctar in forum C Programming
    Replies: 7
    Last Post: 05-12-2010, 10:04 AM
  2. Formatting a text file...
    By dagorsul in forum C Programming
    Replies: 12
    Last Post: 05-02-2008, 03:53 AM
  3. Print file in binary mode
    By vikernes in forum C++ Programming
    Replies: 6
    Last Post: 02-25-2006, 12:43 AM
  4. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  5. Unknown Memory Leak in Init() Function
    By CodeHacker in forum Windows Programming
    Replies: 3
    Last Post: 07-09-2004, 09:54 AM