Thread: Help on fwrite() and fread() an int

  1. #1
    Registered User
    Join Date
    Nov 2011
    Posts
    52

    Help on fwrite() and fread() an int

    Can somebody help me. I am having problems storing a signed long int ('s64') to a file. For some reason when blob.pos is > 127 when I read it from the file it will return junk value.

    I think it has something to do with the endiannes. I checked the bits of blob.pos and the junk value. The rightmost bits of the junk value matched blob.pos but the rest are 1.

    sample:
    junk val - 1111 1111 1111 1111 1111 1111 1101 0110 : -43
    blob.pos - 0000 0000 0000 0000 0000 0000 1101 0110 : 214

    Here's my fwrite code.
    Code:
    fwrite(&(blob.pos), sizeof(s64), 1, fp);
    Thank you for your help.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    The one-liner you posted looks fine. I might use sizeof(blob.pos) just to be sure it's writing the correct number of bytes. Print out sizeof(s64) as well, and make sure that's what you think it is. Are you sure blob.pos has 8 bytes to write out? Maybe that junk is from adjacent memory. If that doesn't sort it out, post the smallest compilable bit of code that demonstrates the problem.

  3. #3
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    The only thing that causes this is casting the value to a signed char and then casting back to a larger integer type. You should look for code which is doing that.
    Note that you've only shown 32-bits here. I assume the other 32-bits are all one or all zero?
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  4. #4
    Registered User
    Join Date
    Nov 2011
    Posts
    52
    Quote Originally Posted by iMalc View Post
    The only thing that causes this is casting the value to a signed char and then casting back to a larger integer type. You should look for code which is doing that.
    Note that you've only shown 32-bits here. I assume the other 32-bits are all one or all zero?
    iMalc you are right I am casting char to a larger int. I was hoping I can do this

    Code:
    FILE *fp;
        fp = fopen("c:\\test.tst","wb");
    
        if(fp) {
            int pos = 500;
            char buf[8];
            fwrite(&pos, sizeof(int), 1, fp);
            fclose(fp);
    
            fp = fopen("c:\\test.tst", "rb");
            if(fp) {
                fread(&pos, sizeof(int), 1, fp); // Put the val to pos - works
                fseek(fp, 0, SEEK_SET); // Put the fp pos at start
                fread(&buf, sizeof(int), 1, fp); // Put the val to buf
    
                printf("%d : %d\n", pos, (int)buf); // (int)buf) will print junk
            }
        }
    Just read the int from file to a char buf then just cast it to int but I guess there is no way to do that. This is just a portion of what I am trying to do. buf[] can have different data types (char, short, int) and I will just cast the buf at the right offset like

    pos = (int)buf[4];
    st = (char)buf[5];

    is there any way to do this?

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    When using an array without the [ ], you effectively have a pointer to the first element. You're casting &buf[0] to an int on line 16. That is definitely not what you want. You could do *((int *) buf). That casts buf (a char pointer) to an int pointer, then dereferences it, giving you the int at that address.

    If you do
    Code:
    pos = (int)buf[4];
    You are taking the char at buf[4] and casting that to an int. A char is just a tiny, one-byte integer, so all the compiler does there is fill out the extra bytes based on the sign bit of the char, if it has one. If you want to cast a short from the middle of the buffer, you have to use pointer cast and dereference trick, along with the & and [ ]:
    Code:
    short s = *((short *) &buf[5]);  // get a short int from buf[5] and buf[6]

  6. #6
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    or printf("%d %d\n", pos, *(int *)buf);

  7. #7
    Registered User
    Join Date
    Nov 2011
    Posts
    52
    Wow that works guys @@, thanks a lot!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. fread, fwrite
    By thescratchy in forum C Programming
    Replies: 2
    Last Post: 03-17-2010, 09:01 AM
  2. fread() & fwrite()
    By Roger in forum C Programming
    Replies: 2
    Last Post: 11-09-2009, 04:18 PM
  3. fwrite and fread help
    By jverkoey in forum C++ Programming
    Replies: 2
    Last Post: 02-12-2003, 10:17 PM
  4. fwrite and fread
    By condorx in forum C Programming
    Replies: 5
    Last Post: 06-08-2002, 12:01 AM
  5. fread() and fwrite() ?
    By Limblet in forum C Programming
    Replies: 4
    Last Post: 09-25-2001, 07:36 PM