>>Maybe he was really tired.
Nope
>>Or perhaps, he was on the phone.
Maybe, I can't remember, but it was a busy day
>>I believe that currently the "b" attributes are just hold overs for compatibility with old compilers
>>as far as the C language is concerned, there is no difference between the two
Not so, read on.
>>http://www.rt.com/man/fopen.3.html
This is a Unix man page, and as such can have a biased opinion on life.
OK, enough of the quotes, let's get down to business. When I wrote my original post, my brain was thinking faster than I could type, and unfortunately I never got to finish my sentence. This is where the confusion comes from. I don't need to go into any details of fwrite/fread as they've already been covered by everyone in this thread (heavy-weight thread it is too, eh?!). The problem, comes from the OP's use of fseek() on the file stream, that is used for fread() and fwrite(). They are quite clearly attempting to open the file, fseek() to a specific struct instance, and then fread() it in; and to do that they must use a binary stream. fseek() requires different parameters depending on the stream mode. To save me waffling on about it, here's the C99 rules for it:
Code:
ISO/IEC 9899:1999 (E)
7.19.9.2 The fseek function
1 #include <stdio.h>
int fseek(FILE *stream, long int offset, int whence);
3 For a binary stream, the new position, measured in characters from the beginning of the
file, is obtained by adding offset to the position specified by whence. The specified
position is the beginning of the file if whence is SEEK_SET, the current value of the file
position indicator if SEEK_CUR, or end-of-file if SEEK_END. A binary stream need not
meaningfully support fseek calls with a whence value of SEEK_END.
4 For a text stream, either offset shall be zero, or offset shall be a value returned by
an earlier successful call to the ftell function on a stream associated with the same file
and whence shall be SEEK_SET.
So, you can see that the OPs use of fseek() is illegal; this is where I was coming from in my original post.
I presume that reason for the difference in behaviour of fseek() is purely because of the problems generated by the OS's need to control how an EOL marker looks in an external file. For example, in text mode, how can you seek to a specific byte offset in the file, when you don't know for sure how many bytes you're traversing in the underlying system? Did the programmer ask for an N-byte offset with expanded EOLs or contracted EOLs, who knows? No-one, so seeking on text mode files is not feasible.
So, in summary, I'll change my original line to:
- fseek() requires the file to be opened in binary mode, when used in the context of the OPs code.
Sorry for not stating the obvious in the first place, I can see I've caused you all to think hard for no reason.
For the reader, here is some code to help your test this out.
Code:
#include <stdio.h>
/*
* Change this mode parameter to the desired one to see the different effects
*/
#define MODE "r+"
/* #define MODE "r+b" */
struct foo
{
int i;
};
int main(void)
{
struct foo bar[2] = {10, 20};
FILE *fp;
if ((fp = fopen("test.bin", MODE)) == NULL)
{
perror ("test.bin");
return 0;
}
/* Write both structs */
fwrite (bar, sizeof (bar), 1, fp);
/* Point to second struct */
fseek(fp, sizeof(bar[0]), SEEK_SET);
/* Read second struct back into first struct in the array */
fread (bar, sizeof (bar[0]), 1, fp);
fclose(fp);
printf ("This should say 20: %d\n", bar[0].i);
return(0);
}
/*
Output when run in binary mode:
This should say 20: 20
Output when run in text mode (might be different on your compiler):
This should say 20: 5120
*/