Thread: Read Bytes From File Into Integer

  1. #16
    Chad Johnson
    Join Date
    May 2004
    Posts
    154
    Yea I don't think I really knew what I was talking about with the bit-shift thing. But your bit-shift idea is good. The only thing I don't like is the processor-dependent storage, which could mess things up. That could be a real problem.

    So with the way the libraries are written, fread should take care of the storage type, correct? Should initializing the variable that I am passing to fread to 0 solve the problem?

  2. #17
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    I wanted to emphasize how important it to understand all of the assumptions you must make when dealing with binary files. Text files are (usually) easier to deal with, and unless you are really concerned about file size, it may not be worth the sacrifice in portability.

    There are lots of systems where int data types are not 32-bit quantities. There are lots of systems that are big-endian. Etc., etc.

    Regards,

    Dave

  3. #18
    Registered User glUser3f's Avatar
    Join Date
    Aug 2003
    Posts
    345
    ChadJohnson:

    If I had to do your program, I'd go with char for 1 byte fields, and int for 2-4 bytes fields, or short for 2 bytes, and int for 4 bytes. (not that I mean int is always 4 bytes or short is always 2 bytes)

    I'd also use fread/fwrite with sizeof.

  4. #19
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    IMO, the best way to do this would be to store the lengths in whatever variable you see fit inside your program. I guess a straight forward integer would be good enough. Then, when it comes to writing this information to the file, call a wrapper function that will take care of formatting it correctly to become 1, 2 or 4 bytes in length. A similar wrapper function can be called to read this back in.

    As for bit shifting, if you have them available, lookup the htonl() type functions, that convert CPU ordered bytes to a common external format, and back again. This will help you with the endian issues.

    Some advice: don't hard code the lengths in the middle of function calls, like this:
    >fwrite (&number, 2, 1, fp);
    This will get you into trouble later. This may be going off track a bit for you, but here's an example of how you might control this type of thing:
    Code:
     #include <stdio.h>
      
      typedef enum {LT_1, LT_2, LT_4, LT_COUNT } LengthType_t;
      const int LengthTypeLengths[LT_COUNT] = { 1, 2, 4 };
      
      int main(void)
      {
        int i;
        LengthType_t myLT = LT_4;
        
        for (i = 0; i < LT_COUNT; i++)
        {
      	printf ("LT_%d has a length of %d\n", 
      			i+1, LengthTypeLengths[i]);
        }
        
        printf ("The length of an LT_2 is %d\n", 
      		  LengthTypeLengths[LT_2]);
        
        printf ("The length of myLT is %d\n", 
      		  LengthTypeLengths[myLT]);
        
        return 0;
      }
      
      /*
      
      Output:
      
      LT_1 has a length of 1
      LT_2 has a length of 2
      LT_3 has a length of 4
      The length of an LT_2 is 2
      The length of myLT is 4
      
      */
    This type of code would set you up for writing a wrapper function that could be invoked like so:
    Code:
      WriteData (MyData, strlen(MyData), LT_1, fp);
    You could use #define's to achieve a similar result, but they rather limit what you can do in the future (thinking ahead here!).
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  5. #20
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    Not sure if this is correct but it seems to work?
    Code:
    #include<iostream>
    using namespace std;
    
    
    int main()
    {
    
    
    
    	FILE *fp = fopen ("data.txt", "wb");
    int myValue = 1500;
    
    fwrite (&myValue, (sizeof(char)*2), 1, fp);
    
    fclose(fp);
    
    int newValue=0;
    fp=fopen("data.txt","rb");
    fread(&newValue,(sizeof(char)*2),1,fp);
    	
    	
    cout<<newValue;	
    	
    	
    fclose(fp);	
    	
    	return 0;
    }
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  6. #21
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    You all seem to have overlooked the obvious...
    Code:
    #include <stdio.h>
    int main( void )
    {
            printf("%d is the size of a short\n", (int)sizeof( short int ) );
            printf("%d is the size of an unsigned short\n", (int)sizeof( unsigned short int ) );
            return 0;
    }
    Quzah.
    Hope is the first step on the road to disappointment.

  7. #22
    End Of Line Hammer's Avatar
    Join Date
    Apr 2002
    Posts
    6,231
    >>You all seem to have overlooked the obvious..
    Not really, I think you've missed the point, or am I misunderstanding you? Its not about determining the size of a different integer variable types, more how to have differing length indicators in an external file. At least, that's how I took it.
    ChadJohnson said:
    I created a file of my own format, and I have different [integer] data items that span two or more bytes.
    >>manofsteel972
    >>Not sure if this is correct but it seems to work?
    It might be close if this were the C++ forum.
    When all else fails, read the instructions.
    If you're posting code, use code tags: [code] /* insert code here */ [/code]

  8. #23
    Chad Johnson
    Join Date
    May 2004
    Posts
    154
    Well hey thanks, I really do appreciate all the help from everybody. I will definitely look into the different options that you all showed me.

    Right now I am going to just hard-code the byte lengths, then I will go back and do the wrapping that you suggested or something to that effect.

  9. #24
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    char is always 1 byte always. so this should give you two bytes. when I open the file in binary i just see two bytes DC 05 which is hex for 1500.
    Well I think i changed it to c code. Oh and by the way you do have to initialize the variable to 0. I tried it without and got the same results as you with a huge number.

    Code:
    #include<cstdio>
    
    
    int main()
    {
    
    
    
    FILE *fp = fopen ("data.txt", "wb");
    int myValue = 1500;
    
    fwrite (&myValue, (sizeof(char)*2), 1, fp);
    
    fclose(fp);
    
    int newValue=0;
    fp=fopen("data.txt","rb");
    fread(&newValue,(sizeof(char)*2),1,fp);
    	
    	
    printf("%i",newValue);	
    	
    	
    fclose(fp);	
    	
    	return 0;
    }
    Last edited by manofsteel972; 08-14-2004 at 08:56 PM.
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  10. #25
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by Hammer
    >>You all seem to have overlooked the obvious..
    Not really, I think you've missed the point, or am I misunderstanding you? Its not about determining the size of a different integer variable types, more how to have differing length indicators in an external file. At least, that's how I took it.
    You misunderstood my solution, or rather, the origional "problem":
    Quote Originally Posted by ChadJohnson
    Now, how do I read this integer value from the file, [b]since it's stored across two bytes[/b ], and get 1500 as an integer again?
    They wanted a two byte integeral data type. Oddly enough, the standard provides just such a data type. That was my "solution". Why bother trying to shift over two bytes so you can write them one byte at a time, when you can instead use a short, rather than an int, and just fwrite it normally?

    There's no point in creating extra work for yourself when you don't need to, unless it's some fun challenge. But I hardly consider a standard fwrite issue fun or challenging.

    Quzah.
    Hope is the first step on the road to disappointment.

  11. #26
    Registered User manofsteel972's Avatar
    Join Date
    Mar 2004
    Posts
    317
    I think he was referring to the problem that the size of the data types is not standard accross all systems so an int on one machine could be some other size instead of 4 bytes and a short could be some other size other than 2 bytes.
    "Knowledge is proud that she knows so much; Wisdom is humble that she knows no more."
    -- Cowper

    Operating Systems=Slackware Linux 9.1,Windows 98/Xp
    Compilers=gcc 3.2.3, Visual C++ 6.0, DevC++(Mingw)

    You may teach a person from now until doom's day, but that person will only know what he learns himself.

    Now I know what doesn't work.

    A problem is understood by solving it, not by pondering it.

    For a bit of humor check out xkcd web comic http://xkcd.com/235/

  12. #27
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by manofsteel972
    I think he was referring to the problem that the size of the data types is not standard accross all systems so an int on one machine could be some other size instead of 4 bytes and a short could be some other size other than 2 bytes.
    The standard sets a minimum size of 16 bits for a short. Thus, since they need something that size, why not use what's there for you?

    Furthermore, who cares what size they are on what system? They don't have to have a fully portable binary. It's just being written and read on the same machine. Additionally, had you paid attention to my post, you'd have seen the answer there before you anyway: Find out what size of variables your system uses, and use the appropriate one.

    You are all over-complicating. Rereading, I see someone else suggested short also. But, as it's been stated elsewhere, you cannot have a platform independant binary file. Period. So why bother trying? Use text if you want platform independance. Otherwise, use the appropriate sized variable for your system, and stop worrying about it.

    Quzah.
    Hope is the first step on the road to disappointment.

  13. #28
    Chad Johnson
    Join Date
    May 2004
    Posts
    154
    Aren't JPEGs platform-independent?

    I have the program written now. The source is a bit messy, so I'll post when I clean it up. It works great.

    I simply said

    Code:
    int byteVal;
    
    byteVal = 0;
    
    fread (&byteVal, 2, 1, fp);
    and it worked great. Initializing the input variable to 0 was the key. I think someone must have misinterpretted what I was saying about storing two bytes in an integer.

    I am planning on eventually using a wrapper as Hammer suggested.

  14. #29
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Quote Originally Posted by ChadJohnson
    Aren't JPEGs platform-independent?
    I suppose I worded that poorly. You can define a standard form of file, but the way it is read by each platform will not be the same. An example is the "endian" issue. The file will always be the same, but each implementation that reads it must do so differently to get the correct results.

    You can read four bytes, but if the way those four bytes are ordered by the read are different between two machines...

    At any rate, my point was, there is a (commonly) two-byte data field for C, so since you're writing two bytes, why don't you just use it?
    [/beating a dead horse]

    Quzah.
    Hope is the first step on the road to disappointment.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. File transfer- the file sometimes not full transferred
    By shu_fei86 in forum C# Programming
    Replies: 13
    Last Post: 03-13-2009, 12:44 PM
  2. Link List math
    By t014y in forum C Programming
    Replies: 17
    Last Post: 02-20-2009, 06:55 PM
  3. Replies: 7
    Last Post: 02-06-2009, 12:27 PM
  4. Replies: 3
    Last Post: 03-02-2008, 12:33 PM
  5. load gif into program
    By willc0de4food in forum Windows Programming
    Replies: 14
    Last Post: 01-11-2006, 10:43 AM