fread to a struct

Discussion in 'C Programming' started by vippstar@gmail.com, Jan 2, 2008.

  1. Guest

    -- foo.c --
    #include <stdio.h>

    int main(void) {

    struct { int a; int b; } foo;
    fread(&foo, sizeof foo, 1, stdin);
    return 0;
    }
    -- foo.c --

    Is there any problem with the above snippet?
    In particular, with reading a struct with fread like that, instead of
    reading each member seperately.
     
    , Jan 2, 2008
    #1
    1. Advertising

  2. <> wrote in message
    news:...
    > -- foo.c --
    > #include <stdio.h>
    >
    > int main(void) {
    >
    > struct { int a; int b; } foo;
    > fread(&foo, sizeof foo, 1, stdin);
    > return 0;
    > }
    > -- foo.c --
    >
    > Is there any problem with the above snippet?
    > In particular, with reading a struct with fread like that, instead of
    > reading each member seperately.


    What you expect may not happen. I guess stdin is opened for reading in text
    mode , not binary mode.
    fread and fwrite reads and writes in binary (raw bytes).
     
    Ravishankar S, Jan 2, 2008
    #2
    1. Advertising

  3. said:

    > -- foo.c --
    > #include <stdio.h>
    >
    > int main(void) {
    >
    > struct { int a; int b; } foo;
    > fread(&foo, sizeof foo, 1, stdin);
    > return 0;
    > }
    > -- foo.c --
    >
    > Is there any problem with the above snippet?


    Add:

    printf("[%d] [%d]\n", foo.a, foo.b);

    after the fread, recompile, and test. Whilst this cannot prove that there
    is not a problem with the snippet, it may be able to prove that there /is/
    a problem.

    I doubt very much whether you will get the results you desire!

    > In particular, with reading a struct with fread like that, instead of
    > reading each member seperately.


    If it was written like that, it can be read like that on the same platform
    (same compiler, same switch settings, yadayadayada). So you can do this:

    #include <stdio.h>
    #define TESTFILE "test.foo"
    int main(void)
    {
    struct { int a; int b; } foo = { 6, 42 };
    FILE *fpw = fopen(TESTFILE, "wb");
    if(fpw != NULL)
    {
    int ok = 0;
    printf("before write: foo.a = %d\nfoo.b = %d\n", foo.a, foo.b);
    fwrite(&foo, 1, sizeof foo, fpw);
    ok = !ferror(fpw);
    fclose(fpw);
    if(ok)
    {
    FILE *fpr = fopen(TESTFILE, "rb");
    if(fpr != NULL)
    {
    foo.a = 10; foo.b = 20; /* any old junk, just to prove the point */
    printf("after reset: foo.a = %d\nfoo.b = %d\n", foo.a, foo.b);
    fread(&foo, 1, sizeof foo, fpr);
    if(!ferror(fpr))
    {
    printf("after read: foo.a = %d\nfoo.b = %d\n", foo.a, foo.b);
    }
    fclose(fpr);
    }
    }
    }
    return 0;
    }

    This code has been (rather cursorily) tested, and a bug removed. One kudos
    point available to whoever can work out what the bug was.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jan 2, 2008
    #3
  4. Guest

    On Jan 2, 1:51 pm, Richard Heathfield <> wrote:
    > This code has been (rather cursorily) tested, and a bug removed. One kudos
    > point available to whoever can work out what the bug was.

    I'd assume that you pass nmemb, size to fread/fwrite and not size,
    nmemb.

    Thanks for the replies, I know what to do now.
     
    , Jan 2, 2008
    #4
  5. said:

    > On Jan 2, 1:51 pm, Richard Heathfield <> wrote:
    >> This code has been (rather cursorily) tested, and a bug removed. One
    >> kudos point available to whoever can work out what the bug was.

    > I'd assume that you pass nmemb, size to fread/fwrite and not size,
    > nmemb.


    In fact, I did get them the wrong way round, not that it matters
    particularly, so well spotted, but no, that wasn't the bug (which, I
    stress, was *fixed* in the posted code).

    > Thanks for the replies, I know what to do now.


    Excellent.

    --
    Richard Heathfield <http://www.cpax.org.uk>
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999
     
    Richard Heathfield, Jan 2, 2008
    #5
  6. "Ravishankar S" <> writes:
    > <> wrote in message
    > news:...
    >> -- foo.c --
    >> #include <stdio.h>
    >>
    >> int main(void) {
    >>
    >> struct { int a; int b; } foo;
    >> fread(&foo, sizeof foo, 1, stdin);
    >> return 0;
    >> }
    >> -- foo.c --
    >>
    >> Is there any problem with the above snippet?
    >> In particular, with reading a struct with fread like that, instead of
    >> reading each member seperately.

    >
    > What you expect may not happen. I guess stdin is opened for reading in text
    > mode , not binary mode.
    > fread and fwrite reads and writes in binary (raw bytes).


    No, fread reads (as if) by repeated calls to fgetc. If the stream is
    opened in text mode, it will read in text mode; if it's opened in
    binary mode, it will read in binary mode. (Likewise for fwrite
    repeatedly calling fputc.)

    Because of this, reading in text mode using fread rarely makes sense;
    it's *intended* to be used in binary mode.

    In the above code, the fread() call will attempt to read sizeof(foo)
    bytes in text mode from stdin, and store them in foo. If you're
    expecting to type "10 20" and have the values 10 and 20 stored in
    foo.a and foo.b, you'll be disappointed.

    --
    Keith Thompson (The_Other_Keith) <>
    [...]
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 2, 2008
    #6
  7. SM Ryan Guest

    wrote:
    # -- foo.c --
    # #include <stdio.h>
    #
    # int main(void) {
    #
    # struct { int a; int b; } foo;
    # fread(&foo, sizeof foo, 1, stdin);
    # return 0;
    # }
    # -- foo.c --
    #
    # Is there any problem with the above snippet?

    ANSI C does not guarentee sizeof struct foo will be the same
    for different compilers or different versions of the same
    compilers or different compilations of the same compilers.
    Unless you can get a guarentee from the compilers you're
    interested in, it's safer to read and write individual int
    fields yourself.

    --
    SM Ryan http://www.rawbw.com/~wyrmwif/
    I hope it feels so good to be right. There's nothing more
    exhilarating pointing out the shortcomings of others, is there?
     
    SM Ryan, Jan 2, 2008
    #7
  8. Tor Rustad Guest

    wrote:
    > -- foo.c --
    > #include <stdio.h>
    >
    > int main(void) {
    >
    > struct { int a; int b; } foo;
    > fread(&foo, sizeof foo, 1, stdin);
    > return 0;
    > }
    > -- foo.c --
    >
    > Is there any problem with the above snippet?
    > In particular, with reading a struct with fread like that, instead of
    > reading each member seperately.


    First problem is the *padding* issue in struct. Hence, different
    versions of your compiler may break this code, or different compilers
    may use different alignment of struct members, and finally just changing
    compiler setting differently... may break it.

    The second problem is endianness. If 'foo' is orginating from a
    hetrogenious system, the code may brake.

    --
    Tor < | tr i-za-h a-z>
     
    Tor Rustad, Jan 3, 2008
    #8
  9. Tor Rustad <> writes:
    > wrote:
    >> -- foo.c --
    >> #include <stdio.h>
    >>
    >> int main(void) {
    >>
    >> struct { int a; int b; } foo;
    >> fread(&foo, sizeof foo, 1, stdin);
    >> return 0;
    >> }
    >> -- foo.c --
    >>
    >> Is there any problem with the above snippet?
    >> In particular, with reading a struct with fread like that, instead of
    >> reading each member seperately.

    >
    > First problem is the *padding* issue in struct. Hence, different
    > versions of your compiler may break this code, or different compilers
    > may use different alignment of struct members, and finally just
    > changing compiler setting differently... may break it.
    >
    > The second problem is endianness. If 'foo' is orginating from a
    > hetrogenious system, the code may brake.


    And the 3rd through Nth problems are all the other possible variations
    in representation. For the structure shown, the possible variations
    include:
    Different number of bytes in an int.
    Different number of bits in a byte.
    Different padding bits within an int.
    Different representations for negative int values.

    The last three are relatively unlikely.

    --
    Keith Thompson (The_Other_Keith) <>
    [...]
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 4, 2008
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. news.amnet.net.au

    Equivalent of "fread" C function in Java

    news.amnet.net.au, Jan 15, 2004, in forum: Java
    Replies:
    2
    Views:
    4,802
  2. Patrick
    Replies:
    6
    Views:
    876
    Roedy Green
    Jul 13, 2004
  3. Chris Fogelklou
    Replies:
    36
    Views:
    1,405
    Chris Fogelklou
    Apr 20, 2004
  4. fread fwrite struct

    , Mar 30, 2006, in forum: C Programming
    Replies:
    4
    Views:
    477
    Michael Mair
    Mar 31, 2006
  5. Hetware
    Replies:
    16
    Views:
    1,144
    gwowen
    Aug 10, 2011
Loading...

Share This Page