 |
C++Talk.NET C++ language newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Andrew Kibler Guest
|
Posted: Thu Oct 27, 2005 4:56 pm Post subject: Simple fwrite after getc macro question.. |
|
|
Two sections of code, in the first one fwrite works, in the second one
it doesn't (ms VC++) both are identical except in the working one fseek
is used twice to set the file pointer, once just before the fwrite.
WHY???
Works:
fseek(fp, itemloc, SEEK_SET);
tmp = ReadLongBE(fp);
if (*itemsize == tmp){
printf("n%Xn",ftell(fp));
fseek(fp, itemloc + 4, SEEK_SET); //added to make fwrite
work.
r += fwrite(itemdata, 1, *itemsize, fp);
printf("n%Xn",ftell(fp));
Just goes through the motions, but doesn't write (even returns proper
values!!)
fseek(fp, itemloc, SEEK_SET);
tmp = ReadLongBE(fp);
if (*itemsize == tmp){
printf("n%Xn",ftell(fp));
//no fseek, but ftell is correct.
r += fwrite(itemdata, 1, *itemsize, fp); //but this doesn't actually
write!!
printf("n%Xn",ftell(fp)); //but the file pointer is advanced
properly
BOTH return the same values for ftell before and after the write.
The second one doesn't wrrite, but acts like it does during the debug.
The ReadLongBE (big endian) macro:
#define ReadLongBE(Stream) ((getc(Stream)<<24) + (getc(Stream)<<16) +
(getc(Stream)<< + (getc(Stream)))
Thanks!
|
|
| Back to top |
|
 |
Paul Jarc Guest
|
Posted: Thu Oct 27, 2005 5:30 pm Post subject: Re: Simple fwrite after getc macro question.. |
|
|
Andrew Kibler <00 (AT) cwru (DOT) edu> wrote:
| Quote: | fseek(fp, itemloc, SEEK_SET);
tmp = ReadLongBE(fp);
if (*itemsize == tmp){
printf("n%Xn",ftell(fp));
fseek(fp, itemloc + 4, SEEK_SET); //added to make fwrite work.
r += fwrite(itemdata, 1, *itemsize, fp);
|
When reading and then writing on the same stream, the C standard
requires an fseek/fsetpos/rewind in between, unless the read reached
EOF. Writing and then reading requires fflush/fseek/fsetpos/rewind in
between. (See C99+TC2 (WG14/N1124) 7.19.5.3p6.) Any given
implementation may or may not work without the fseek; yours apparently
doesn't. The usual idiom, which you might like to wrap up in a macro
or function, is fseek(fp, ftell(fp), SEEK_SET). Or, if you want to
check for errors and be able to handle file positions that don't fit
in long:
int reset_fp(FILE* fp) {
fpos_t pos;
if (fgetpos(fp, &pos)!=0) return -1;
if (fsetpos(fs, &pos)!=0) return -1;
return 0;
}
paul
|
|
| Back to top |
|
 |
red floyd Guest
|
Posted: Thu Oct 27, 2005 5:31 pm Post subject: Re: Simple fwrite after getc macro question.. |
|
|
Andrew Kibler wrote:
| Quote: | [fwrite after fread question redacted]
Thanks!
|
I don't have a copy of the C standard (only the C++ standard) available,
but I believe that's defined as required. That is, after you fread, you
*must* fseek before you fwrite.
Unfortunately, that's one of the "included by reference to C standard"
areas. Anyone got the C standard?
|
|
| Back to top |
|
 |
TIT Guest
|
Posted: Thu Oct 27, 2005 5:34 pm Post subject: Re: Simple fwrite after getc macro question.. |
|
|
Andrew Kibler sade:
| Quote: | Two sections of code, in the first one fwrite works, in the second one
it doesn't (ms VC++) both are identical except in the working one fseek
is used twice to set the file pointer, once just before the fwrite.
WHY???
|
Let me quote the C99 Standard 7.19.5.3/6:
"When a file is opened with update mode [...], both input and
output may be performed on the associated stream. However,
output shall not be directly followed by input without an
intervening call to the fflush function or to a file positioning
function (fseek, fsetpos, or rewind), and input shall not be directly
followed by output without an intervening call to a file positioning
function, unless the input operation encounters end-of-file.[...]"
TIT
|
|
| Back to top |
|
 |
Andrew Kibler Guest
|
Posted: Thu Oct 27, 2005 5:43 pm Post subject: Re: Simple fwrite after getc macro question.. |
|
|
| Quote: | When reading and then writing on the same stream, the C standard
requires an fseek/fsetpos/rewind in between, unless the read reached
EOF.
|
Thanks for your fast reply. I was using
http://www.cplusplus.com/ref/cstdio/fwrite.html
as my resource, and they don't have that requirement documented
Strange that you have to do that.. after all, that's the point of the
file pointer, no? Having to flush the write buffer before a read makes
sense, though. Strange that fwrite would return the correct value,
too. Oh well.
|
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|