Re: fwrite
- From: Michael Mair <Michael.Mair@xxxxxxxxxxxxxxx>
- Date: Sat, 16 Jul 2005 22:26:13 +0200
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. .
- Follow-Ups:
- Re: fwrite
- From: cs
- Re: fwrite
- References:
- fwrite
- From: cs
- Re: fwrite
- From: Michael Mair
- Re: fwrite
- From: cs
- fwrite
- Prev by Date: Is there any ANSI method to extract/tokenize argv[ ]
- Next by Date: Re: Is there any ANSI method to extract/tokenize argv[ ]
- Previous by thread: Re: fwrite
- Next by thread: Re: fwrite
- Index(es):
Relevant Pages
|