Re: fwrite



cs wrote:
On Sat, 16 Jul 2005 10:33:25 +0200, Michael Mair
<Michael.Mair@xxxxxxxxxxxxxxx> wrote:

Please provide code which can compile -- I do not know whether
the mistakes you make (FILE instead of FILE*, pf/fp etc) are just
because you were to lazy to provide a compiling minimal example
and _paste_ it unchanged or because you are not in the least
aware of what you are doing.

As you are trying to show us your question by pseudo-code, it
should be made clear what the question is.


i don't know if this compile but
the question is why this program has the result down?

Yes, it compiles. Sorry, you once more failed to tell what you _expected_.

Are you talking about the output? If yes: What did you expect
instead? Did you want to test rand() or your I/O procedure?

#include <stdio.h> #include <stdlib.h>

typedef struct{
  unsigned   a;

a is used to denote the size of an array. If you want to make these arrays to be able have >= 65536 elements, do not use unsigned int as type for a but use long (up to (1L<<31)-1 elements), unsigned long (up to 2L*(1L<<31) - 1 elements) or, best, size_t (as many elements as fit on your machine). Note that these limits can be exceeded on your machine and your implementation but these are what is _guaranteed_.

  unsigned  *b;
}tp;


int main(void) { int i; unsigned val[90]={0}; tp e; size_t k; FILE *fp; /**********************/ e.a=90; e.b=val;

Note: you are using a "magic number" (90). This may well bite you later on if changing not all occurrences of 90 correctly. Rather use symbolic constants or compute values, i.e. #define NUM_VAL 90 .... unsigned val[NUM_VAL] = {0}; .... e.a = NUM_VAL; or e.a = sizeof val/sizeof val[0]; /* works only in the scope where * the array val has been declared.*/

for(i=0; i<e.a; ++i) e.b[i]=rand();

Why are you using rand()? If you want to compare whether what has been written is read back correctly, rather use values you know or, if you insist on rand(), use a second array to read it in so you can compare directly or at least write out the contents of val _immediately_ after setting them.

if( (fp=fopen("file.dat", "w")) == 0 ) return 0;

exit(EXIT_FAILURE); preceded by an appropriate error message may be a better solution.

  k=fwrite(&e.a, sizeof(unsigned), 1, fp);
  if(k<1) {fclose(fp); return 0;}

  k=fwrite(e.b, sizeof(unsigned), e.a, fp);
  if(k<e.a) {fclose(fp); return 0;}
  if( fclose(fp)==EOF )  printf("W Error\n");

Note: If you open file.dat in mode "w+", it suffices to rewind(fp) to start reading.

for(i=0; i<e.a; ++i) {printf("e.b[%d]=%x ", i, e.b[i]); e.b[i]=0; }

Note: Use an iteration variable of the same type as e.a. otherwise you may have the funny effect that e.a has a value larger than the possible maximum value for i which results in an overflow for i and thus undefined behaviour (which may lead to an endless loop).

printf("\n");
if( (fp=fopen("file.dat", "r")) == 0 ) {printf("fopen"); goto la;}

Note: Most people will verbally hang, draw, disembowel and quarter you happily for use of goto. Almost all will do so for such an unnecessary and badly documented use of goto. The la: label is rather hidden than made obvious. It seems you were just too lazy to type the rest of the error message a second time. Use goto only to make _clearer_ what happens (which can be the case if you want a one-exit function or have lenghty clean-up code) or if you can _prove_ that its use is absolutely necessary to squeeze the _necessary_ bit of performance out of some critical piece of code (which is the case in about one in a million cases; some other cases may make do with a cleaner construct, most improve with the use of a better algorithm).


  k=fread(&e.a, sizeof(unsigned), 1, fp);

if(e.a>20000 || k<1 || ferror(fp)) {fclose(fp); return 0;}

Note that you throwing up on _very_ different things. k<1 and ferror(fp) may go together as they document input errors. e.a>20000 (why not 90? -- Ah, the joys of magic numbers) documents "wrong input value" which has nothing to do with the rest.

Consider writing an errMsgExit() function which outputs
a string to stderr and exit(EXIT_FAILURE)s.

k=fread(e.b, sizeof(unsigned), e.a, fp);
/* if(k<e.a || ferror(fp)) {fclose(fp); printf("E0 k=%u e.a=%u\n", (unsigned) k, e.a); return 0;
}
*/ if( fclose(fp)==EOF ) {la:;
printf("R Error\n");
}

If you _ever_ _need_ a goto, at least document the labels as good as you can. e.g. if( fclose(fp)==EOF ) { la: printf("R Error\n"); } Do add empty statements only if necessary (which is hardly ever the case in C89).


for(i=0; i<e.a; ++i) {printf("e.b[%d]=%x ", i, e.b[i]); e.b[i]=0; }

Why are you resetting e.b[i] without need?
  printf("\n");

  return  0;
}

/* result */
e.b[0]=82 e.b[1]=2ae6 e.b[2]=442 e.b[3]=2d88 e.b[4]=1bcd e.b[5]=44bb
e.b[6]=190f e.b[7]=59a4 e.b[8]=7996 e.b[9]=232c e.b[10]=38de
e.b[11]=df3 e.b[12]=595f e.b[13]=483c e.b[14]=550 e.b[15]=1524
e.b[16]=6861 e.b[17]=57bf e.b[18]=61d7 e.b[19]=69ef e.b[20]=7ad1
e.b[21]=1c16 e.b[22]=36a1 e.b[23]=79ee e.b[24]=6b75 e.b[25]=762c
e.b[26]=67cb e.b[27]=39bb e.b[28]=4d68 e.b[29]=54b1 e.b[30]=4cc3
e.b[31]=464b e.b[32]=5c29 e.b[33]=e96 e.b[34]=33fe e.b[35]=f8b
e.b[36]=55eb e.b[37]=3cc9 e.b[38]=3edc e.b[39]=4839 e.b[40]=2c18
e.b[41]=6f32 e.b[42]=21d8 e.b[43]=1704 e.b[44]=3627 e.b[45]=58ee
e.b[46]=14f4 e.b[47]=44e7 e.b[48]=529f e.b[49]=4fcb e.b[50]=64
e.b[51]=64c3 e.b[52]=226c e.b[53]=3b04 e.b[54]=317a e.b[55]=303b
e.b[56]=4a62 e.b[57]=4d3e e.b[58]=23d1 e.b[59]=15d5 e.b[60]=670f
e.b[61]=25c2 e.b[62]=2abd e.b[63]=344e e.b[64]=1ec6 e.b[65]=34fd
e.b[66]=6f3 e.b[67]=3f3e e.b[68]=7de9  e.b[69]=35   e.b[70]=3475
e.b[71]=8ed e.b[72]=976 e.b[73]=208d   e.b[74]=7cc1 e.b[75]=2
d74 e.b[76]=33d4 e.b[77]=193c e.b[78]=193a e.b[79]=1b18 e.b[80]=1fe0
e.b[81]=610a e.b[82]=71d6 e.b[83]=73e3 e.b[84]=5e33 e.b[85]=3b0c
e.b[86]=440a e.b[87]=484 e.b[88]=10b7 e.b[89]=3aa0
e.b[0]=82 e.b[1]=2ae6 e.b[2]=442 e.b[3]=2d88 e.b[4]=1bcd e.b[5]=44bb
e.b[6]=190f e.b[7]=59a4 e.b[8]=7996 e.b[9]=232c e.b[10]=38de
e.b[11]=5f0000f3 e.b[12]=3c000059 e.b[13]=50000048 e.b[14]=24000005
e.b[15]=61000015 e.b[16]=bf000068 e.b[17]=d7000057 e.b[18]=ef000061
e.b[19]=d1000069 e.b[20]=1600007a e.b[21]=a100001c e.b[22]=ee000036
e.b[23]=75000079 e.b[24]=2c00006b e.b[25]=cb000076 e.b[26]=bb00006
7 e.b[27]=68000039 e.b[28]=b100004d e.b[29]=c3000054 e.b[30]=4b00004c
e.b[31]=29000046 e.b[32]=9600005c e.b[33]=fe00000e e.b[34]=8b000033
e.b[35]=eb00000f e.b[36]=c9000055 e.b[37]=dc00003c e.b[38]=3900003e
e.b[39]=18000048 e.b[40]=3200002c
e.b[41]=d800006f e.b[42]=4000021 e.b[43]=27000017 e.b[44]=ee000036
e.b[45]=f4000058 e.b[46]=e7000014 e.b[47]=9f000044 e.b[48]=cb000052
e.b[49]=6400004f e.b[50]=c3000000 e.b[51]=6c000064 e.b[52]=4000022
e.b[53]=7a00003b e.b[54]=3b000031 e.b[55]=62000030 e.b[56]=3e00004a
e.b[57]=d100004d e.b[58]=d5000023 e.b[59]=f000015  e.b[60]=c2000067
e.b[61]=bd000025 e.b[62]=4e00002a e.b[63]=c6000034 e.b[64]=fd00001e
e.b[65]=f3000034 e.b[66]=3e000006 e.b[67]=e900003f e.b[68]=3500007d
e.b[69]=75000000 e.b[70]=ed000034 e.b[71]=76000008 e.b[72]=8d000009
e.b[73]=c1000020 e.b[74]=7400007c e.b[75]=d400002d e.b[76]=3c000033
e.b[77]=3a000019 e.b[78]=18000019 e.b[79]=e000001b e.b[80]=a00001f
e.b[81]=d6000061 e.b[82]=e3000071 e.b[83]=33000073 e.b[84]=c00005e
e.b[85]=a00003b e.b[86]=84000044 e.b[87]=b7000004 e.b[88]=a0000010
e.b[89]=3a

On my machine, everything looks well. Does the value of e.b[11] also go wrong for NUM_VAL 12 or is this keyed to 90?


Cheers Michael

Have a look at

#include  <stdio.h>
#include  <stdlib.h>

typedef struct{
  size_t     a;
  unsigned  *b;
}tp;

#define MAX_VAL 90UL

static void errMsgExit(const char *msg, FILE *fp)
{
  (void)fclose(fp);
  if (msg)
    (void)fputs(msg, stderr);
  exit(EXIT_FAILURE);
}

int main(void)
{
  size_t              i;
  unsigned  val[MAX_VAL]={0};
  unsigned rval[MAX_VAL]={0};
  tp                  e = {0,0};
  tp                  r = {0,0};
  size_t              k;
  FILE              *fp;
/**********************/
  e.a = MAX_VAL; e.b = val;
  r.b = rval;

  for(i=0; i<e.a; ++i) e.b[i]=rand();

  if( (fp=fopen("file.dat", "w+")) == NULL )
    errMsgExit("W Error on opening file\n", NULL);
  k=fwrite(&e.a, sizeof(unsigned), 1, fp);
  if(k<1)
    errMsgExit("W Error on writing size\n", fp);

  k=fwrite(e.b, sizeof(unsigned), e.a, fp);
  if(k<e.a)
    errMsgExit("W Error on writing array contents\n", fp);

/*
  for(i=0; i<e.a; ++i)
    printf("e.b[%lu]=%x ", (unsigned long)i, e.b[i]);
  printf("\n");
*/
  rewind(fp);

  k=fread(&r.a, sizeof r.a, 1, fp);

  if(k<1 || ferror(fp)!=0)
    errMsgExit("R Error on reading size\n", fp);
  if (r.a != e.a)
    errMsgExit("R Error wrong size\n", fp);

  k=fread(r.b, sizeof *r.b, r.a, fp);
  if(k<r.a || ferror(fp)!=0)
    errMsgExit("R Error on reading array\n", fp);

  if( fclose(fp)==EOF )
  {
    errMsgExit("R Error closing file\n", NULL);
  }

  for(i=0; i<e.a; ++i)
    if (e.b[i] != r.b[i])
      printf("e.b[%lu]=%x r.b[%lu]=%x\n",
             (unsigned long)i, e.b[i],
             (unsigned long)i, r.b[i]);
  printf("\n");

  return  0;
}

--
E-Mail: Mine is an   /at/ gmx /dot/ de   address.
.



Relevant Pages

  • Re: reading prose out loud
    ... generated reading would not achieve the same effect. ...  And enticing the computerized voice to speak the rhythms ... and a computerized voice seems to be a good ... not terminally lazy. ...
    (rec.arts.sf.composition)
  • Re: Guilianis right hand position.
    ... Thanks Howard!!! ... You know I only have vision in my left eye so I've had to train my brain ... to accept lazy reading as my sin. ...
    (rec.music.classical.guitar)
  • Re: Return recordset from stored procedure
    ... things so far as I've been lazy and done no reading... ... Then want to store some data relating to that file in a db table ... Then change the name of the uploaded file to the @@IDENTITY value. ... I guess if you could also mention some great reading on understanding ...
    (microsoft.public.dotnet.csharp.general)
  • Re: OT: Shades of gray?
    ... Just FYI - I'm out of this one - not even reading this morning. ... please accept my apologies for being too lazy to check. ... Not killing in self defense, but cold-blooded, premeditated murder. ... far as I can see I don't see how anyone who claim to believe the Bible can say that breaking any commandment is a shade of gray - they were written in stone. ...
    (sci.med.transcription)
  • Re: Matlab code error
    ... I'm a little lazy and don't want to run your code, but with an error message I am more inclined to at least try to help. ... Nathan, when you respond to a thread you should include your response in the thread itself rather than starting a brand new thread, as you have done here. ... I guess google group's "new" view doesn't work correctly with TMW newsgroup? ...
    (comp.soft-sys.matlab)