Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > fread()

Reply
Thread Tools

fread()

 
 
Josh Wilson
Guest
Posts: n/a
 
      07-12-2004
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[i] = (double) floatarray[i];
}
}
.....
for(i=0; i<INDIM; i++){
if (dfloatarray[i] > max2){
max2 = dfloatarray[i];
}
}

for (i=0;i<istat;i++){
floatarray[i] = (float) dfloatarray[i];
}
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));
}
}
 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      07-13-2004
http://www.velocityreviews.com/forums/(E-Mail Removed) (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[i] = (double) floatarray[i];


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[i] > max2){
> max2 = dfloatarray[i];
> }
> }
>
> for (i=0;i<istat;i++){
> floatarray[i] = (float) dfloatarray[i];
> }
> 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
 
Reply With Quote
 
 
 
 
Barry Schwarz
Guest
Posts: n/a
 
      07-13-2004
On 12 Jul 2004 13:07:47 -0700, (E-Mail Removed) (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[i] = (double) floatarray[i];


The cast is unnecessary.

> }
> }
>....
> for(i=0; i<INDIM; i++){
> if (dfloatarray[i] > max2){
> max2 = dfloatarray[i];
> }
> }
>
> for (i=0;i<istat;i++){
> floatarray[i] = (float) dfloatarray[i];
> }
> 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>>
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off




Advertisments