question about fread function

X

xiao

Hi~ every one~ I have a queston about fread function. if i have a
code like this:
(nscrdh and data are defined as two dementional arrays and both of
them were stored in the same binary file)

fread(&nscrdh,sizeof(nscrdh),1,in);
fread(&data,sizeof(data),1,in);

How can i know where the second fread start? Is it just start from the
end of the first fread? Or somewhere else?
Because i tried to write "data" first and read them out. But after i
read it out , the value is differet from the original.

Thanks~
 
W

Walter Roberson

Hi~ every one~ I have a queston about fread function. if i have a
code like this:
(nscrdh and data are defined as two dementional arrays and both of
them were stored in the same binary file)

How can i know where the second fread start? Is it just start from the
end of the first fread? Or somewhere else?

Yes, the second would start at the next available byte after the
first had finished.
 
C

CBFalconer

Eric said:
xiao said:
[...]
(nscrdh and data are defined as two dementional arrays [...]

C does not have two-dementional arrays. C's arrays are
one-dimensional, but an array element can itself be an array,
thus giving the appearance of a two-dimensional array. So
you should not call them two-dementional, but two-delusional.

I consider this sub-thread demented. :)
 
B

Barry Schwarz

xiao said:
[...]
(nscrdh and data are defined as two dementional arrays [...]

C does not have two-dementional arrays. C's arrays are
one-dimensional, but an array element can itself be an array,
thus giving the appearance of a two-dimensional array. So
you should not call them two-dementional, but two-delusional.

I agree that this is the most practical way to think of the situation.
But the C99 standard does in fact call such an array a
"multidimensional array object" (6.5.2.1-3). One example (6.7.8) is
even called a "three-dimensional array object".
 
P

Pranav

fread(&nscrdh,sizeof(nscrdh),1,in);
fread(&data,sizeof(data),1,in);

If your data members 'data' and 'nscrdh' are structures the sizeof()
operator returns the size of the structures with padding. Then you
may accidentally read the next few bytes., Probably this may the bug
haunting your code.
So better you use #pragma pack to optimise the structure by packing
it.

Also you can use ftell() to know the point where the pointer is
pointing.
 
X

xiao

fread(&nscrdh,sizeof(nscrdh),1,in);
fread(&data,sizeof(data),1,in);

If your data members 'data' and 'nscrdh' are structures the sizeof()
operator returns the size of the structures with padding. Then you
may accidentally read the next few bytes., Probably this may the bug
haunting your code.
So better you use #pragma pack to optimise the structure by packing
it.

Also you can use ftell() to know the point where the pointer is
pointing.

Thank you guys ~ but how can I find the right point? Using fseek or
something like that?
Actually, I write the data like this:

Write2DArrayInt(cumulus, ncolumns,nrows, out); /*Write2DArrayInt
is a function and out is the file pointer. cumuls is definded as
short **cumulus ncolumns=2030, nrows=1354 */

void Write2DArrayInt(short **Array, int Columns, int Rows, FILE *fp)
{
int i;

for(i=0; i<Rows; i++){
fwrite(Array, sizeof(short),Columns, fp);
}
}

And read it like this:
fread(&data,sizeof(data),1,in); /*data is defind as short **data
*/

AND i tried to print some values like this:

fread(&data,sizeof(data),1,in);
for (i=0 ;i<10 ; i++){
for (j=0 ;j<10 ;j++)
printf(" %hd \t",data[j]);
}/*this is in after the values are written*/

And

for(i=0; i<10; i++){
for(j=0; j<10; j++){printf(" %hd\t",cumulus
[j]);
}} /*this is before the value are written*/

But their values are totally different, why is that? :)
 
P

Pranav

fread(&nscrdh,sizeof(nscrdh),1,in);
fread(&data,sizeof(data),1,in);
If your data members 'data' and 'nscrdh' are structures the sizeof()
operator returns the size of the structures with padding. Then you
may accidentally read the next few bytes., Probably this may the bug
haunting your code.
So better you use #pragma pack to optimise the structure by packing
it.
Also you can use ftell() to know the point where the pointer is
pointing.

Thank you guys ~ but how can I find the right point? Using fseek or
something like that?
Actually, I write the data like this:

Write2DArrayInt(cumulus, ncolumns,nrows, out); /*Write2DArrayInt
is a function and out is the file pointer. cumuls is definded as
short **cumulus ncolumns=2030, nrows=1354 */

void Write2DArrayInt(short **Array, int Columns, int Rows, FILE *fp)
{
int i;

for(i=0; i<Rows; i++){
fwrite(Array, sizeof(short),Columns, fp);
}

}

And read it like this:
fread(&data,sizeof(data),1,in); /*data is defind as short **data
*/

AND i tried to print some values like this:

fread(&data,sizeof(data),1,in);
for (i=0 ;i<10 ; i++){
for (j=0 ;j<10 ;j++)
printf(" %hd \t",data[j]);
}/*this is in after the values are written*/

And

for(i=0; i<10; i++){
for(j=0; j<10; j++){printf(" %hd\t",cumulus
[j]);
}} /*this is before the value are written*/

But their values are totally different, why is that? :)





If you have defined the data as "short **data" or "short *data[]"
then sizeof() operator wont give you the correct size of the chunk you
want read from the file. Please check your code by hard coding the
chunk you write and read once OR check your value returned by sizeof()
operator. Try it by creating new empty file.
If you have any doubts reply/ask the group only do not mail any one.


Pranav
-- There's a difference between knowing the path and walking it.
 
X

xiao

Thank you guys ~ but how can I find the right point? Using fseek or
something like that?
Actually, I write the data like this:
Write2DArrayInt(cumulus, ncolumns,nrows, out); /*Write2DArrayInt
is a function and out is the file pointer. cumuls is definded as
short **cumulus ncolumns=2030, nrows=1354 */
void Write2DArrayInt(short **Array, int Columns, int Rows, FILE *fp)
{
int i;
for(i=0; i<Rows; i++){
fwrite(Array, sizeof(short),Columns, fp);
}

And read it like this:
fread(&data,sizeof(data),1,in); /*data is defind as short **data
*/

AND i tried to print some values like this:
fread(&data,sizeof(data),1,in);
for (i=0 ;i<10 ; i++){
for (j=0 ;j<10 ;j++)
printf(" %hd \t",data[j]);
}/*this is in after the values are written*/

for(i=0; i<10; i++){
for(j=0; j<10; j++){printf(" %hd\t",cumulus
[j]);
}} /*this is before the value are written*/

But their values are totally different, why is that? :)

If you have defined the data as "short **data" or "short *data[]"
then sizeof() operator wont give you the correct size of the chunk you
want read from the file. Please check your code by hard coding the
chunk you write and read once OR check your value returned by sizeof()
operator. Try it by creating new empty file.
If you have any doubts reply/ask the group only do not mail any one.

Pranav
-- There's a difference between knowing the path and walking it.


haha,thank you~~~ :)
 
K

Keith Thompson

Pranav said:
fread(&nscrdh,sizeof(nscrdh),1,in);
fread(&data,sizeof(data),1,in);

If your data members 'data' and 'nscrdh' are structures the sizeof()
operator returns the size of the structures with padding. Then you
may accidentally read the next few bytes., Probably this may the bug
haunting your code.
So better you use #pragma pack to optimise the structure by packing
it.

Also you can use ftell() to know the point where the pointer is
pointing.

Since you didn't quote any context from the article to which you were
replying, it's hard to tell what you're referring to. And since the
actual parent article was discussing multidimensional arrays, it's
nearly impossible to figure out what you mean.

The size of the structures with padding is the size of the structures;
in other words, the padding is part of the structures. If you're
reading and writing the same data using the same program on the same
implementation, then writing and reading the same structure using
fwrite and fread should give you back the original data. (There's
probably no guarantee for any padding bytes, but that's ok, since you
don't care about the values of padding bytes.)

Using "#pragma pack" (a) isn't likely to help, and (b) isn't portable
anyway (it's an extension, not a feature of the language).

In any case, the original post made it clear that data and nscrdh are
arrays.
 
S

santosh

Keith Thompson wrote:

The size of the structures with padding is the size of the structures;
in other words, the padding is part of the structures. If you're
reading and writing the same data using the same program on the same
implementation, then writing and reading the same structure using
fwrite and fread should give you back the original data. (There's
probably no guarantee for any padding bytes, but that's ok, since you
don't care about the values of padding bytes.)

Using "#pragma pack" (a) isn't likely to help, and (b) isn't portable
anyway (it's an extension, not a feature of the language).

Would it be unfeasible to standardise #pragma pack, seeing as it's such
a common extension? I suppose there are machines out there that cannot
function without the required alignment?
 
P

Pranav

Keith Thompson wrote:




Would it be unfeasible to standardise #pragma pack, seeing as it's such
a common extension? I suppose there are machines out there that cannot
function without the required alignment?

Its not purely machine dependent it depends on OS/Compiler/
Processor..., And two dimensional array can contain structure
variable. So..., Till and until Xiao defines his code properly we
cannot go further assuming things randomly..,

Pranav
 
K

Keith Thompson

santosh said:
Keith Thompson wrote:


Would it be unfeasible to standardise #pragma pack, seeing as it's such
a common extension? I suppose there are machines out there that cannot
function without the required alignment?

It's always *possible* to pack structure members tightly with no
padding bytes. Suppose you have something like:

struct foo { char c; double d; };
#pragma pack /* whatever the syntax is */

on an implementation that cannot access a double other than on an
8-byte boundary. Then the compiler could generate extra code to copy
the ``d'' member to or from an aligned temporary, using memcpy or an
equivalent. This becomes difficult when you take the address of such
a member:

struct foo obj;
double *d = &obj;
*d += 42.0;

so that *all* uses of double* pointers have to allow for the
possibility that the target is misaligned. Unless the compiler is
very clever, this could slow down code that doesn't use packed
structures.

But it's always possible.

Whether it's worth standardizing is another matter. And whether the
committee could reach a consensus on standardizing it is yet another.
 
N

Nick Keighley

no. sizeof returns the size of the struct

? how do you "accidently" read a few bytes?


no, do NOT use #pragma pack. Its non-portable and may not even be
available
on some implentations.


what do you mean by the "right point"? ftell() tells you where abouts
in the file you are. Only you can tell if this is the "right point".


Using fseek or something like that?

I think you need to decide what you are trying to do.

Actually, I write the data like this:

post a complete, compilable program that exhibits your problem.
Explain what it does and what you want it to do. Don't post fragments
of programs


Write2DArrayInt(cumulus, ncolumns,nrows, out);     /*Write2DArrayInt
is a function and out is the file pointer.  cumuls is definded as
short **cumulus ncolumns=2030, nrows=1354 */

void Write2DArrayInt(short **Array, int Columns, int  Rows,  FILE *fp)
{
        int  i;

        for(i=0; i<Rows; i++){
             fwrite(Array, sizeof(short),Columns, fp);
        }
}

And read it like this:
 fread(&data,sizeof(data),1,in);    /*data is defind as short **data
*/

AND i tried to print some values like this:

fread(&data,sizeof(data),1,in);
 for (i=0 ;i<10 ; i++){
    for (j=0 ;j<10 ;j++)
    printf(" %hd \t",data[j]);
  }/*this is in after the values are written*/

And

              for(i=0; i<10; i++){
                    for(j=0; j<10; j++){printf(" %hd\t",cumulus
[j]);
              }} /*this is before the value are written*/

But their values are totally different, why is that?  :)
 
I

Ian Collins

Keith said:
It's always *possible* to pack structure members tightly with no
padding bytes. Suppose you have something like:

struct foo { char c; double d; };
#pragma pack /* whatever the syntax is */

on an implementation that cannot access a double other than on an
8-byte boundary. Then the compiler could generate extra code to copy
the ``d'' member to or from an aligned temporary, using memcpy or an
equivalent. This becomes difficult when you take the address of such
a member:

struct foo obj;
double *d = &obj;
*d += 42.0;

so that *all* uses of double* pointers have to allow for the
possibility that the target is misaligned. Unless the compiler is
very clever, this could slow down code that doesn't use packed
structures.

The only compiler I've used that did something like this was Sun cc on
Sparc. Every misaligned access generates a trap and the bytes are read
or written by the trap handler. Dog slow when there are lots of
misaligned accesses, but no impact when there are none.
 
C

CBFalconer

Nick said:
no. sizeof returns the size of the struct

Not so. It has to include padding, which is arranged so that
arrays of those structs have individual members correctly aligned.
 
V

vippstar

Not so. It has to include padding, which is arranged so that
arrays of those structs have individual members correctly aligned.

"sizeof returns the size of the struct" is correct.
He did not say
"sizeof returns the sum of the sizeof each individual member of the
struct" (applied recursively)
 
K

Keith Thompson

CBFalconer said:
Not so. It has to include padding, which is arranged so that
arrays of those structs have individual members correctly aligned.

The size of the struct, by definition, includes any padding.
 
C

CBFalconer

"sizeof returns the size of the struct" is correct.
He did not say "sizeof returns the sum of the sizeof each
individual member of the struct" (applied recursively)

He was denying that such a sizeof included the padding involved.
 
N

Nick Keighley

    ^^



He was denying that such a sizeof included the padding involved.

no I wasn't. sizeof returns the size of the struct and that
includes the padding. "sizeof() operator returns the size of the
structures with padding" implies to me, that the poster thinks there
are two types of struct size; one with padding and one without.
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Similar Threads


Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,070
Latest member
BiogenixGummies

Latest Threads

Top