fread()

Discussion in 'C Programming' started by Josh Wilson, Jul 12, 2004.

  1. Josh Wilson

    Josh Wilson Guest

    The fread() is what I believe is having trouble, but I do not know
    why. I know that the temp file is created and written to (and w/ the
    appropriate amount of data). fread() continues to return 0, but I
    don't know why it shouldn't work; but when I used ferror(stdin) and it
    gives 0 suggesting to me it read w/o problem, so I'm confused since I
    know there is information in the file, and it is allegedly reading
    from stdin, any help please?

    Thanks!


    #define FLOAT 0
    #define DOUBLE 6
    #define INDIM 32768
    #include <stdio.h>
    #include <math.h>


    main (argc,argv)
    int argc;
    char **argv;
    {
    double dfloatarray[INDIM];
    float floatarray[INDIM];
    int i,istat,iaccum,intype;
    int iostat;
    float max2=0;
    FILE *tempfile;
    char s[L_tmpnam];
    char *p = tmpnam(s);


    if (norm == 1){
    iaccum = 0;
    tempfile = fopen(p,"a");
    while(feof(stdin) == 0){
    if (intype == FLOAT) { /*By this time, intype does = FLOAT
    */
    istat = fread(floatarray,4,INDIM,stdin);
    iaccum+=istat;
    for (i=0; i<istat; i++){
    dfloatarray = (double) floatarray;
    }
    }
    .....
    for(i=0; i<INDIM; i++){
    if (dfloatarray > max2){
    max2 = dfloatarray;
    }
    }

    for (i=0;i<istat;i++){
    floatarray = (float) dfloatarray;
    }
    iostat=fwrite(floatarray,4,istat,tempfile);
    freopen(p,"r",stdin);
    }

    if (intype == FLOAT)
    istat = fread(floatarray,4,INDIM,stdin);
    /*This is where it seems to fall apart.*/
    fprintf(stderr,"ferror = %d", ferror(stdin));
    }
    }
     
    Josh Wilson, Jul 12, 2004
    #1
    1. Advertising

  2. Josh Wilson

    Richard Bos Guest

    (Josh Wilson) wrote:

    > #define FLOAT 0
    > #define DOUBLE 6
    > #define INDIM 32768
    > #include <stdio.h>
    > #include <math.h>
    >
    > main (argc,argv)
    > int argc;
    > char **argv;


    Whoah! Get into the ISO age... this is very old-fashioned C. You'd get a
    lot of benefits if you started to use prototypes. In this case:

    int main(int argc, char **argv)

    > {
    > double dfloatarray[INDIM];
    > float floatarray[INDIM];
    > int i,istat,iaccum,intype;
    > int iostat;
    > float max2=0;
    > FILE *tempfile;
    > char s[L_tmpnam];
    > char *p = tmpnam(s);
    >
    >
    > if (norm == 1){


    What is this norm? It isn't declared above, and it's not Standard,
    either.

    > iaccum = 0;
    > tempfile = fopen(p,"a");


    You do realise that you're opening tempfile as a _text_ stream, not a
    binary stream? And that this could distort any binary data you write
    using fwrite()? Better is

    tempfile=fopen(p, "ab");

    > while(feof(stdin) == 0){


    This is not the best way to read from a stream. It's in the FAQ:
    <http://www.eskimo.com/~scs/C-faq/q12.2.html>.

    > if (intype == FLOAT) { /*By this time, intype does = FLOAT */


    Are you very sure of that? Your indentation makes this hard to notice,
    but the statement which reads back your data depends on this.

    > istat = fread(floatarray,4,INDIM,stdin);


    What I said above about writing binary data to a text stream is also
    true for reading. Of course, stdin _is_ a text stream.
    Besides, reading binary data from standard input? Do you expect your
    users to enter the IEEE representation of a float by hand, or are you
    sure you'll always pipe in the binary output of another program?

    Also, get rid of the hard-coded 4. Sooner or later, it will trip you up.
    Use sizeof (float), or even better, sizeof *floatarray, instead.

    > iaccum+=istat;


    I presume you initialise istat somewhere? 'Cause if not, you've got a
    problem here.

    > for (i=0; i<istat; i++){
    > dfloatarray = (double) floatarray;


    The cast is unnecessary. For one, any valid float _must_ be
    representable as a double.

    > }
    > }
    > ....


    So what _is_ the code that went missing here? Does it perhaps do
    something to dfloatarray? Does it read another kind of data if intype !=
    FLOAT, and set istat accordingly?

    > for(i=0; i<INDIM; i++){


    In both other loops you use a limit of istat, yet here you use INDIM,
    potentially reading uninitialised array members.

    > if (dfloatarray > max2){
    > max2 = dfloatarray;
    > }
    > }
    >
    > for (i=0;i<istat;i++){
    > floatarray = (float) dfloatarray;
    > }
    > iostat=fwrite(floatarray,4,istat,tempfile);


    You do nothing with iostat. You do not even check that _it_ is not 0, or
    indeed anything but istat. Why not?
    And vide supra for the hard-coded 4.

    > freopen(p,"r",stdin);


    This freopen() is inside your reading loop, meaning that for the second
    batch of floats you do not actually read from standard input, but from
    your temp file. Provided, of course, that the freopen() succeeded, which
    is far from guaranteed since you already have the same file open for
    appending - if _that_ call succeeded, that is, which you don't check for
    any more than you check this one.

    > }
    >
    > if (intype == FLOAT)
    > istat = fread(floatarray,4,INDIM,stdin);


    Note that if intype is not FLOAT, you read nothing, but istat keeps its
    old value - which is likely to be 0, since the last time it was changed
    was by an fread() which we can only suppose read 0 objects from an empty
    stdin.
    Again, get rid of the 4.

    > /*This is where it seems to fall apart.*/
    > fprintf(stderr,"ferror = %d", ferror(stdin));


    And when all is said and done, fread() returning 0 does not necessarily
    mean that a read error occured. It may also mean that you're not reading
    from the file you expect to be reading from, but are reading from a file
    which really _does_ contain 0 objects - what, for example, if that
    freopen() failed?

    I note that you close no files. This may cause problems later on. It may
    also cause problems now, if you try to open one twice.

    > }
    > }


    Since main() returns an int, you should actually return one.

    return 0;

    Richard
     
    Richard Bos, Jul 13, 2004
    #2
    1. Advertising

  3. On 12 Jul 2004 13:07:47 -0700, (Josh Wilson)
    wrote:

    >The fread() is what I believe is having trouble, but I do not know
    >why. I know that the temp file is created and written to (and w/ the
    >appropriate amount of data). fread() continues to return 0, but I
    >don't know why it shouldn't work; but when I used ferror(stdin) and it
    >gives 0 suggesting to me it read w/o problem, so I'm confused since I
    >know there is information in the file, and it is allegedly reading
    >from stdin, any help please?
    >
    >Thanks!
    >
    >
    >#define FLOAT 0
    >#define DOUBLE 6
    >#define INDIM 32768
    >#include <stdio.h>
    >#include <math.h>
    >
    >
    >main (argc,argv)
    >int argc;
    >char **argv;


    Not yet illegal but really obsolete.

    >{
    > double dfloatarray[INDIM];
    > float floatarray[INDIM];
    > int i,istat,iaccum,intype;
    > int iostat;
    > float max2=0;
    > FILE *tempfile;
    > char s[L_tmpnam];
    > char *p = tmpnam(s);
    >
    >
    >if (norm == 1){


    What is norm?

    > iaccum = 0;
    > tempfile = fopen(p,"a");
    > while(feof(stdin) == 0){


    feof does not do what you imply by this construct.

    > if (intype == FLOAT) { /*By this time, intype does = FLOAT


    intype is currently uninitialized.

    >*/
    > istat = fread(floatarray,4,INDIM,stdin);


    fread does no conversion at all. How do you expect to enter the
    binary representation of 32000+ floating point numbers from the
    keyboard? Better to use sizeof(float) instead of 4.

    > iaccum+=istat;
    > for (i=0; i<istat; i++){
    > dfloatarray = (double) floatarray;


    The cast is unnecessary.

    > }
    > }
    >....
    > for(i=0; i<INDIM; i++){
    > if (dfloatarray > max2){
    > max2 = dfloatarray;
    > }
    > }
    >
    > for (i=0;i<istat;i++){
    > floatarray = (float) dfloatarray;
    > }
    > iostat=fwrite(floatarray,4,istat,tempfile);
    > freopen(p,"r",stdin);


    Do you ever really get here?

    > }
    >
    >if (intype == FLOAT)
    > istat = fread(floatarray,4,INDIM,stdin);
    >/*This is where it seems to fall apart.*/
    >fprintf(stderr,"ferror = %d", ferror(stdin));
    > }
    >}




    <<Remove the del for email>>
     
    Barry Schwarz, Jul 13, 2004
    #3
    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,815
  2. Patrick
    Replies:
    6
    Views:
    887
    Roedy Green
    Jul 13, 2004
  3. Axel
    Replies:
    12
    Views:
    668
  4. Replies:
    3
    Views:
    4,905
    Sharad Kala
    May 4, 2004
  5. Brady

    problem using fread, fwrite, and fsetpos

    Brady, Jul 17, 2003, in forum: C Programming
    Replies:
    8
    Views:
    967
    Dave Thompson
    Jul 21, 2003
Loading...

Share This Page