Thread: need Help! reading a binary file

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    10

    Question need Help! reading a binary file

    Hi guys, I have question. I haven’t program in c++ in over 5 years last time I was programming I was learning the langrage in school. I now have jump back into programming in c++ and i am trying to make a program that would be able to read a binary file and get the data from it. so i can save it to a text file.

    Code:
    
    
    This is how the data is structured.
    
    ------------------------------------------------
    Size (Bytes)  	     Name  	      Type  	      Description
    -------the structure of the file--------------------------------------------
      4 	                         Signature 	  char[4] 	    File Signature ('logi') no terminating null
      4 	                         version 	    uint32 	      File Format Version
      4 	                         count 	      uint32 	      Number of entries that follow
    
    Variable 	entries
    -----------------------------------------------------
    1 	              namelenth 	uint8 	      Length of name
    namelenth 	      name 	      char[] 	      name (nameLength characters) no terminating null
    6 	              id 	        uint8[6] 	    HEXVALUE   
    8                 FILETIME    FILETIME      100-nanosecond increments since January 1, 1601 (UTC). 64-bit integer
    ------------------------------------------------------------------------
    
    
    here is a hex example of the file(paste it in to your hex editor and save it)
    ------------------------------------
    6C6F676905000000010000000D5468697369737468656E616D65000A11F1D11160992BFCD425C901
    ------------------------------------
    
    Lets break it down
    ----------------------------------------------------------
    
    6C6F6769 = logi                                Signature
    05000000 = 5                                    version
    01000000 = 1                                    count
    ----------------------------------------------------------
    
    0D = 13                                         namelenth
    5468697369737468656E616D65 =  Thisisthename     name
    000A11F1D111 = 000A11F1D111                     HEXVALUE  hex value of name 
    60992BFCD425C901 = 3:55:05 AM  10/4/2008        FILETIME
    ----------------------------------------------------------
    
    Signature = logi
    version = 5
    count = 1
    namelenth = 13
    name = Thisisthename
    HEXVALUE = 000A11F1D111
    FILETIME = 3:55:05 AM  10/4/2008
    
    ---------------------------------------
    I can not change the format of the file it has already been set a long time ago.

    I am not looking for anybody to do this program for me I am just trying to be point in the
    Right direction.

    By the way I don’t have access to visual studio.net IDE

    Currently I am using the free IDE "Bloodshed Software - Dev-C++"

    I need to make this program work with Linux and windows. windows whould be fine right now and it has to be in c/c++

    Any help will be greatly appreciated. thank you.

    --------------------------------------------------------------------------------
    Last edited by d4rksid3; 10-16-2008 at 12:34 AM.

  2. #2
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    Look into the FAQs on this website for examples of small programs that perform I/O.
    Mainframe assembler programmer by trade. C coder when I can.

  3. #3
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    So EXACTLY which part of the problem are you struggling with? How far have you got?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  4. #4
    Registered User
    Join Date
    Oct 2008
    Posts
    10

    Post

    Quote Originally Posted by Dino View Post
    Look into the FAQs on this website for examples of small programs that perform I/O.
    Quote Originally Posted by matsp View Post
    So EXACTLY which part of the problem are you struggling with? How far have you got?

    --
    Mats
    thank you Marsp and Dino for you reply.

    i look in the FAQ about read and writing files and all over the internet(GOOGLE) but I'm not sure if I'm on the right track. here is the code i came up with.

    Code:
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    class Header				
    {
    public:
    	 char  signature[4];			//is logi
    	 unsigned int   version;		//greater than 5
    	 unsigned int   entries;		//number of entries
    };
    
    int main()
    {
    	Header a;
    	ifstream ifs("testfile.dat", ios::binary);		//open file
    	ifs.read((char *)&a, sizeof(Header));			//read varibles
    	cout << "File information\n";					//out put data to console.
    	cout << "Signature: " << a.signature << endl;
    	cout << "FileVersion: " << a.version << endl;
    	cout << "Entries count: " << a.entries << endl;
    	return 0;
    }

    but when i look at the output its not right. what I'm i doing wrong? i attach a picture of the console output.

  5. #5
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Can you verify that sizeof(header) is twelve?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  6. #6
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Quote Originally Posted by matsp View Post
    Can you verify that sizeof(header) is twelve?

    --
    Mats
    Code:
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    class Header				
    {
    public:
    	 char  signature[4];			//is logi
    	 unsigned int   version;		//greater than 5
    	 unsigned int   entries;		//number of entries
    };
    
    int main()
    {
    	Header a;
    	ifstream ifs("testfile.dat", ios::binary);		//open file
    	ifs.read((char *)&a, sizeof(Header));			//read variables
    	cout << "File information\n";					//out put data to console.
    	cout << "Signature: " << a.signature << endl;
    	cout << "FileVersion: " << a.version << endl;
    	cout << "Entries count: " << a.entries << endl;
    	cout <<	"Size of Header: " <<  sizeof(Header) << endl;
    	return 0;
    }
    yes Header is 12;

  7. #7
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Have you checked that read actually succeeds, because the value you are printing is 0xCCCCCCCC, which is MS VS standard fill pattern for "uninitialized stack space", so it appears that read isn't doing what you expect it to do. Are you sure the file is opening correctly?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #8
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Quote Originally Posted by matsp View Post
    Have you checked that read actually succeeds, because the value you are printing is 0xCCCCCCCC, which is MS VS standard fill pattern for "uninitialized stack space", so it appears that read isn't doing what you expect it to do. Are you sure the file is opening correctly?

    --
    Mats
    lol Mats you where right it wasn't opening the file. i had the hex editor open forgot to close it.

    anyways this is what i have now for the output. how do i get rid of the char circle in red. and how would i go about reading the "namelenth" of the file since it is only 1 byte.
    Last edited by d4rksid3; 10-16-2008 at 08:51 AM.

  9. #9
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    You are reading a 4 byte signature and printing it as a null-terminated string - there is no guarantee that there will be a zero to terminate the string...

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  10. #10
    Jack of many languages Dino's Avatar
    Join Date
    Nov 2007
    Location
    Chappell Hill, Texas
    Posts
    2,332
    You would be better served to read the file into a structure that matched the file layout, but then before printing it out, (or using other functions on the data), to copy it into a "well behaved" structure similar to what you have, but making an allowance for the null terminator as well.
    Mainframe assembler programmer by trade. C coder when I can.

  11. #11
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    >> Have you checked that read actually succeeds, because the value you are printing is 0xCCCCCCCC, which is MS VS standard fill pattern for "uninitialized stack space", so it appears that read isn't doing what you expect it to do.

    Nice detective work there, matsp.
    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;
    }

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Quote Originally Posted by Dino View Post
    You would be better served to read the file into a structure that matched the file layout, but then before printing it out, (or using other functions on the data), to copy it into a "well behaved" structure similar to what you have, but making an allowance for the null terminator as well.
    first i like to say thank you to everyone who has tried to help me.

    now I'm stuck.(doesn't surprise you. i know that's why I'm here )
    The problem I am having now is how do i get the "namelength" from the file since it is only 1 byte and how do i add a variable name that is dependent on the namelenth
    To the structure of a class call entries. also how would I get the hex value of the name.

    Code:
    Variable 	entries
    -----------------------------------------------------
    1 	              namelenth 	uint8 	      Length of name
    namelenth 	      name 	      char[] 	      name (nameLength characters) no terminating null
    6 	              id 	        uint8[6] 	    HEXVALUE   
    8                 FILETIME    FILETIME      100-nanosecond increments since January 1, 1601 (UTC). 64-bit integer
    ------------------------------------------------------------------------
    
    
    class Entries				
    {
    public:
            unsigned int8 namelenth;         //get the length of the name on 1 byte
            char name[namelenth];        // get the name      variable number of bytes
             
            
    };

  13. #13
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So read takes, as the second argument, the sizeof the thing you're reading. So, put it there. (In the first case, you can use sizeof(yourvariable); in the second case, you can use the value of nameLength as the size to read.)

  14. #14
    Registered User
    Join Date
    Oct 2008
    Posts
    10
    Quote Originally Posted by tabstop View Post
    So read takes, as the second argument, the sizeof the thing you're reading. So, put it there. (In the first case, you can use sizeof(yourvariable); in the second case, you can use the value of nameLength as the size to read.)
    hi tabstop.
    i know about the part on adding the lenth here is the code and the result the part i dont understand is how to get the namelenth which is 1byte.

    Code:
    #include <fstream>
    #include <iostream>
    using namespace std;
    
    class Header				
    {
    public:
    	 char  signature[4];			//is logi
    	 unsigned int   version;		//greater than 5
    	 unsigned int   entries;		//number of entries
    };
    int main()
    {
    	Header a;
    	ifstream ifs("testfile.dat", ios::binary);		//open file
    	ifs.read((char *)&a, sizeof(Header));			//read variables
    	cout << "File information\n";					//out put data to console.
    	cout << "Signature: " << a.signature << endl;
    	cout << "FileVersion: " << a.version << endl;
    	cout << "Entries count: " << a.entries << endl;
    	cout <<	"Size of Header: " <<  sizeof(Header) << endl; //get the number of entries from the file.
    	unsigned int  lenth; //how do you make this 1 byte int8
    		ifs.read((char *)&lenth,1);
    		cout << "Lenth of name: "  << lenth; //read lenth of name should be 13.
    	return 0;
    }

  15. #15
    Registered User
    Join Date
    Dec 2007
    Posts
    2,675
    signature need to be of size 5 to hold the required terminating null character, which you will need to add yourself; i.e.,
    Code:
    signature[strlen("logi")] = '\0';

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Binary Tree - Reading From and Writing to a File
    By Ctank02 in forum C++ Programming
    Replies: 2
    Last Post: 03-15-2008, 09:22 PM
  2. Possible circular definition with singleton objects
    By techrolla in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2004, 10:46 AM
  3. Problem reading a delimited file into a binary tree
    By neolyn in forum C++ Programming
    Replies: 10
    Last Post: 12-09-2004, 07:51 PM
  4. Reading data from a binary file
    By John22 in forum C Programming
    Replies: 7
    Last Post: 12-06-2002, 02:00 PM
  5. reading from structs in a binary file
    By Unregistered in forum C Programming
    Replies: 4
    Last Post: 12-21-2001, 10:52 AM

Tags for this Thread