why is fread forgetting where its position?

0

010 010

I found this very odd and maybe someone can explain it to me.

I was using fread to scan through a binary file and pull bytes out. In
the middle of a while loop, for no reason that i could discern, fread
all the sudden kept returning the same byte over and over as if it were
no longer advancing in the file. I used a hex editor to determine the
address of the last byte read in the file. CF was the last address, D0
was not ever read although my while loop kept running.

when i tried to use ftell to try to debug the problem, the program ran
fine. mmm, so i took the ftell out and the program ceased working
again. the ftell wasn't doing anything that i could tell. this is my
loop:

while (blah2!=3220) // I'm still working out bugs and using
temporary variables like "blah"
{
fread(&newval,BPS,1,WavInPtr); //put new byte in
newval

blah=oldval^newval[0];

ftell(WavInPtr); // fread forgets about itself
without this


if(blah < 0)
{
oldval = newval[0];
fprintf(WavOutPtr,"%ld \n",period_cntr);
period_cntr=0;

}

++period_cntr;

++blah2;
}

as you can see, ftell isn't attached to anything, it isn't doing
anything that i can see. but if i take it out, the program just runs
fine to a certain point and then stops making sense.

I'm compiling on Dev-c++ 4.9.9.2

I'd be glad to send the source code to anyone who wants to play with it
themselves. it requires a small wav file that comes with it.
 
A

Ancient_Hacker

There are these things called "return values" from library routines.
It's often a good idea to see what they say, like at each and every
function call.

I suspect fread is detecting end of file. Quite possible, if it did
hit end of file, or if you opened up the file in "text" mode.
 
0

010 010

Ancient_Hacker said:
There are these things called "return values" from library routines.
It's often a good idea to see what they say, like at each and every
function call.

thanks much for the sarcasm. Actually, what i posted was the last step
in the debugging process, the bare minimum to get the program to
function. previously i had been printing the result of ftell after
each loop. I saw it incrementing, but i also saw the program function
properly. without this call to ftell (and without it only), the
program does not procede past a certain point in the file. it repeats
the same byte from the middle of the file (or, possibly, returns no
value at all, didn't test for that, oops).
I suspect fread is detecting end of file. Quite possible, if it did
hit end of file, or if you opened up the file in "text" mode.

Ah, i did open the file in text mode. Thank you for pointing that out.
This probably does affect things, however, it doesn't explain how a
call ftell allows the program to read all the way through the file. If
i had hit a data point that had the same bit pattern as an eof (which
it didn't, it hit decimal 31), would it continuoulsy return the same
byte or have no return value at all? or would it scroll off through
memory, reading the next consecutive bits?

Any insight into this quirk would be interesting to hear, thanks.
 
G

Gordon Burditt

There are these things called "return values" from library routines.
thanks much for the sarcasm. Actually, what i posted was the last step
in the debugging process, the bare minimum to get the program to
function. previously i had been printing the result of ftell after
each loop.

Did you also print the result of fread() after you called it?
I saw it incrementing, but i also saw the program function
properly. without this call to ftell (and without it only), the
program does not procede past a certain point in the file. it repeats
the same byte from the middle of the file (or, possibly, returns no
value at all, didn't test for that, oops).

If fread() returns 0 or -1, DON'T EVEN LOOK at the value in the buffer.
Ah, i did open the file in text mode. Thank you for pointing that out.
This probably does affect things, however, it doesn't explain how a
call ftell allows the program to read all the way through the file. If
i had hit a data point that had the same bit pattern as an eof (which
it didn't, it hit decimal 31), would it continuoulsy return the same
byte or have no return value at all? or would it scroll off through
memory, reading the next consecutive bits?

fread() returns an integer value. It cannot return "no return value at all".
 
0

010 010

hey gordon,
Did you also print the result of fread() after you called it?
If fread() returns 0 or -1, DON'T EVEN LOOK at the value in the buffer.

yes, i did. or rather, i put fread into a variable and then printed
that valiable. I kept geting 31.
fread() returns an integer value. It cannot return "no return value at all".

I was pretty sure that this was the case. but since my integer that
fread was retuned into kept giving the same response, the two
possiblities were 1) fread keeps giving the same byte or 2) fread isnt
writing into the memory space of that variable.

The real question is still how does a call to ftell affect the way
fread works, either by affecting the file pointer, or some buffer or
something. atleast, thats what seems to me to be happening, because
adding and subtracting that one call to ftell drastically changes the
output of my program, and the input is not changing at all.

thanks
 
C

Christopher Layne

010 said:
The real question is still how does a call to ftell affect the way
fread works, either by affecting the file pointer, or some buffer or
something. atleast, thats what seems to me to be happening, because
adding and subtracting that one call to ftell drastically changes the
output of my program, and the input is not changing at all.

You're seeing undefined behavior. Most likely because you did something to
create a situation that invokes undefined behavior. ftell() does not affect
fread().

Just give us the whole function source that we can work with or pull things up
in a debugger of some sort - because this is shooting in the dark at this
point unfortunately.
 
A

Ancient_Hacker

I still havent seen any unequivocal statement that you're printing out
the value that fread returns as it's function value. NOT the data
value that it's supposed to return in the first parameter's address.
You shouldnt look at that until you've verified that indeed fread says
it returned something, as indicated by the value it returns.

For extra info, clear out the buffer before the fread, like, put a '?'
into it. I suspect fread will do nothing in that last case and you'll
see a '?' still sitting in the buffer.
 
G

Gordon Burditt

Did you also print the result of fread() after you called it?
yes, i did. or rather, i put fread into a variable and then printed
that valiable. I kept geting 31.

ret = fread(&newbuf, 1, 1, f);

In the above statement, the return value of fread() has everything to do
with the value of ret and nothing whatever to do with what's in newbuf.
You should not look at any values in newbuf until you have verified that
ret > 0.

If your code contains a statement like:

fread(&newbuf, 1, 1, f);

you obviously didn't use the return value of fread(). Replace this statement
with:
remove(__FILE__);

Some bad code should be shot on sight.
 
W

William Hughes

010 said:
hey gordon,


yes, i did. or rather, i put fread into a variable and then printed
that valiable. I kept geting 31.


I was pretty sure that this was the case. but since my integer that
fread was retuned into kept giving the same response, the two
possiblities were 1) fread keeps giving the same byte or 2) fread isnt
writing into the memory space of that variable.

The real question is still how does a call to ftell affect the way
fread works, either by affecting the file pointer, or some buffer or
something. atleast, thats what seems to me to be happening, because
adding and subtracting that one call to ftell drastically changes the
output of my program, and the input is not changing at all.

thanks

At a guess. You are stomping on memory somewhere before the fread
loop.
This memory stomp causes fread to fail. You do not check the
return value of fread and do not know it has failed. When fread fails
it does nothing to the input buffer, so the value that you are looking
at does not change (To check this try resetting newval between calls
to fread). The ftell call either sets the stomped on memory to
something less harmfull, or changes the memory layout in such
a way that the place that gets stomped is different (have you tried
using some other function than ftell, or changing optimization levels?)
The problem probably has little to do with fread or ftell. Try to
find
the memory stomp (do you have any memory debugging tools?)

-William Hughes
 
P

Peter Shaggy Haywood

Groovy hepcat 010 010 was jivin' on 29 Sep 2006 13:05:47 -0700 in
comp.lang.c.
why is fread forgetting where its position?'s a cool scene! Dig it!
I found this very odd and maybe someone can explain it to me.

I was using fread to scan through a binary file and pull bytes out. In
the middle of a while loop, for no reason that i could discern, fread
all the sudden kept returning the same byte over and over as if it were
no longer advancing in the file. I used a hex editor to determine the
address of the last byte read in the file. CF was the last address, D0
was not ever read although my while loop kept running.

when i tried to use ftell to try to debug the problem, the program ran
fine. mmm, so i took the ftell out and the program ceased working
again. the ftell wasn't doing anything that i could tell. this is my
loop:

while (blah2!=3220) // I'm still working out bugs and using
temporary variables like "blah"
{
fread(&newval,BPS,1,WavInPtr); //put new byte in
newval

blah=oldval^newval[0];

ftell(WavInPtr); // fread forgets about itself
without this


if(blah < 0)
{
oldval = newval[0];
fprintf(WavOutPtr,"%ld \n",period_cntr);
period_cntr=0;

}

++period_cntr;

++blah2;
}

Ye gads! Show us something that will compile. Make it legible.
Indent consistently, and not too far at each level. Two to four spaces
per indentation level should be fine. Don't use // comments here. They
have a nasty tendancy to wrap, making it harder for us to copy, paste
and compile your code. Use /* */ comments only, when posting here.
Show us the smallest *complete* program that demonstrates the
problem. By "complete" I mean something you expect to compile and run.
Cut out everything extraneous, anything that does not demonstrate the
problem. (And do try to compile the cut-down version of your code.)
Explain precisely but concisely what you expect the code to do, as
well as what it actually does.
Show us the data you're attempting to work on. If it's non-textual
data, attempt to provide some textual interpretation of this (eg., a
hex dump). Of course, if your dataset is large, you may need to
truncate it.
Without being provided all this information, all we can do is guess
what might be wrong. Remember, you want our help; so you're going to
have to do the work. Help us to help you. You're not likely to get
much help if you just say, effcetively, "Here's an uncompilable,
incomplete and barely legible snippet of code. Why doesn't it work?".
as you can see, ftell isn't attached to anything, it isn't doing
anything that i can see. but if i take it out, the program just runs
fine to a certain point and then stops making sense.

I'm compiling on Dev-c++ 4.9.9.2

I'd be glad to send the source code to anyone who wants to play with it
themselves. it requires a small wav file that comes with it.

Let me guess. You've opened the file in text mode?

--

Dig the even newer still, yet more improved, sig!

http://alphalink.com.au/~phaywood/
"Ain't I'm a dog?" - Ronny Self, Ain't I'm a Dog, written by G. Sherry & W. Walker.
I know it's not "technically correct" English; but since when was rock & roll "technically correct"?
 
C

Chris Torek

Did you also print the result of fread() after you called it?
yes, i did. or rather, i put fread into a variable and then printed
that valiable. I kept geting 31.

Here are the arguments you showed for your fread() call in your
(not compile-able, so perhaps different from actual code) example:

fread(&newval,BPS,1,WavInPtr)

The fread() function takes four parameters:

- a pointer to the object(s) to be set (here &newval)
- the size of those objects (here BPS)
- the number of such objects (here 1)
- the file to read from (here WavInPtr)

The return value from fread() is the number of items successfully
read, which is always between 0 and the third argument inclusive.
Since your third argument is 1, fread() can only return either 0
or 1.

Hence, if you did:

x = fread(&newval, BPS, 1, WavInPtr);
printf("fread returned %d\n", x);

and found that x is 37, something is terribly, horribly wrong.
 
K

Kenneth Brody

010 said:
Ancient_Hacker wrote: [...]
I suspect fread is detecting end of file. Quite possible, if it did
hit end of file, or if you opened up the file in "text" mode.

Ah, i did open the file in text mode. Thank you for pointing that out.
This probably does affect things, however, it doesn't explain how a
call ftell allows the program to read all the way through the file. If
i had hit a data point that had the same bit pattern as an eof (which
it didn't, it hit decimal 31), would it continuoulsy return the same
byte or have no return value at all? or would it scroll off through
memory, reading the next consecutive bits?

Any insight into this quirk would be interesting to hear, thanks.

What was the byte _after_ the 31? Remember, fread will not fill the
buffer with the text-mode EOF character (ie: Ctrl-Z on Windows) if
it hits it. Rather, it will probably keep the previous character
(your "decimal 31") there.

My guess would be that ftell() is internally clearing the "I hit the
Ctrl-Z EOF marker" flag. (Does your program print two 31's at the
point that the ctrl-Z exists?)

Again, as was semi-sarcastically pointed out in Ancient_Hacker's
post, had you been checking the return from fread(), you would have
instead been asking the question "why does fread() claim I've hit
EOF when there are more bytes to read?"

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <mailto:[email protected]>
 
A

Al Balmer

hey gordon,


yes, i did. or rather, i put fread into a variable and then printed
that valiable. I kept geting 31.


I was pretty sure that this was the case. but since my integer that
fread was retuned into kept giving the same response, the two
possiblities were 1) fread keeps giving the same byte or 2) fread isnt
writing into the memory space of that variable.
It sounds like you're confusing the return value of the function with
the values put in your read buffer. The code you posted doesn't even
look at the function return value. Use something like:

int status;
status = fread( ...

Then check the value of status.
 
0

010 010

ok, ok.

Thanks all or the huge response. I apologize to ancient hacker, as i
thought he was talking about the return value of ftell. It is
obviously poor programing to not check the return of fread and just
accept the value in the buffer.

I haven't implemented any of these ideas yet, but i just wanted to say
that i'm on it, so ya'll can take a break from scrutinizing my
fragmented code. hopefully i'll have something better to post in the
next day or so.

also, thanks to shaggy for pointing out some of the finer (or not so
fine) points of posting readable code here.

I feel edified and appreciative: thanks,

010 010
 

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

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,900
Latest member
Nell636132

Latest Threads

Top