Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   problem with feof ? (http://www.velocityreviews.com/forums/t956999-problem-with-feof.html)

mark.babli@gmail.com 01-28-2013 04:08 AM

problem with feof ?
 
hey all,

did c a while back, trying to get back into it. the following stub of code fails on the while(!feof(fp)) for some reason. could someone help? Thanks
Please note that all variables here are indeed declared:

do
{
fgets(line,80,fp);
tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));
if(tmpNode == NULL)
{
perror("unable to allocate memory");
intResult= -2;
}
sscanf(line,"%d:%s",&intVal,strVal,100);
strcpy(tmpNode->chrName,strVal);
tmpNode->intID = intVal;
if(addDoubleNode(tmpNode)<0)
{
perror("unable to create new node...error code (-3)");
exit(-3);
}
}while(!feof(fp)); //On this line the code fails.

Thanks again

Joe Pfeiffer 01-28-2013 04:34 AM

Re: problem with feof ?
 
mark.babli@gmail.com writes:

> hey all,
>
> did c a while back, trying to get back into it. the following stub of code fails on the while(!feof(fp)) for some reason. could someone help? Thanks
> Please note that all variables here are indeed declared:
>
> do
> {
> fgets(line,80,fp);
> tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));
> if(tmpNode == NULL)
> {
> perror("unable to allocate memory");
> intResult= -2;
> }
> sscanf(line,"%d:%s",&intVal,strVal,100);
> strcpy(tmpNode->chrName,strVal);
> tmpNode->intID = intVal;
> if(addDoubleNode(tmpNode)<0)
> {
> perror("unable to create new node...error code (-3)");
> exit(-3);
> }
> }while(!feof(fp)); //On this line the code fails.
>
> Thanks again


What's the symptom? In what sense do you mean "fails"? segfault? some
error that turns up in the debugger? laser blasts from Martians?

Andrew Smallshaw 01-28-2013 04:39 AM

Re: problem with feof ?
 
On 2013-01-28, mark.babli@gmail.com <mark.babli@gmail.com> wrote:
>
> do
> {
> fgets(line,80,fp);
> tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));
> if(tmpNode == NULL)
> {
> perror("unable to allocate memory");
> intResult= -2;
> }
> sscanf(line,"%d:%s",&intVal,strVal,100);
> strcpy(tmpNode->chrName,strVal);
> tmpNode->intID = intVal;
> if(addDoubleNode(tmpNode)<0)
> {
> perror("unable to create new node...error code (-3)");
> exit(-3);
> }
> }while(!feof(fp)); //On this line the code fails.


It looks OK as far as I can see subject to the provisos:

a) We can't see the entire program, nor even the definition of
relevant types and functions. Therefore we must simply take those
on trust.

b) We have no idea what you expect to happen.

c) We have no idea what really is happening. The conditional
controlling a loop essentially has two possible outcomes barring
side effects: the loop is either continued or it isn't. Neither
outcome is a "failure".

What is really happening and how does this compare to what you
expect to happen. You answer should include the exact input the
code is considering.

--
Andrew Smallshaw
andrews@sdf.lonestar.org

Ben Bacarisse 01-28-2013 04:57 AM

Re: problem with feof ?
 
mark.babli@gmail.com writes:

> hey all,
>
> did c a while back, trying to get back into it. the following stub
> of code fails on the while(!feof(fp)) for some reason.


"Fails" is a very general description. What happens?

> could someone
> help? Thanks Please note that all variables here are indeed declared:


That they are declared is not enough! See my comments below.

> do
> {
> fgets(line,80,fp);


How is line declared? There are declarations that will make this line
go horribly wrong! Also, if the call fails you carry on regardless with
indeterminate data in the buffer.

> tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));


tmpNode = malloc(sizeof *tmpNode);

is neater and avoids some of the repetition.

> if(tmpNode == NULL)
> {
> perror("unable to allocate memory");
> intResult= -2;
> }


You carry on even when tmpNode == NULL. If that does ever happen, what
follows will wreak havoc.

> sscanf(line,"%d:%s",&intVal,strVal,100);


The 100 does nothing. Is it supposed to be a buffer size? If so, you
can put the size in the format string and without such a size limit the
sscanf call can overflow the buffer. Also, you don't test to see if
this scan call succeeded. If it fails, the code below could do much
damage.

> strcpy(tmpNode->chrName,strVal);


Ideally, you'd post the declaration of the struct. This could be very
wrong indeed, but I'm guessing that chrName is an array but even then
you don't do anything to protect again too much data being copied.

> tmpNode->intID = intVal;
> if(addDoubleNode(tmpNode)<0)


This function might be doing something wrong as well. Ideally, post a
small complete program that demonstrates the problem.

> {
> perror("unable to create new node...error code (-3)");
> exit(-3);
> }
> }while(!feof(fp)); //On this line the code fails.


It's possible that some previous error is causing the problem. The
general point is that you are not testing for errors (or success where
that is moire useful) and you are not protecting against buffer
overflows.

In general, input loops in C are better written without using feof. The
traditional style is to loop while the input is successful:

while (fgets(line, 80, fp) &&
sscanf(line,"%d:%99s", &intVal, strVal) == 2) {

/* there was a line (though maybe one that was too long) and it
had the right sort of data in it so we can safely proceed to
process it. */
}

/* You can certainly use feof here to check that all went well. */

--
Ben.

Barry Schwarz 01-28-2013 04:57 AM

Re: problem with feof ?
 
On Sun, 27 Jan 2013 20:08:52 -0800 (PST), mark.babli@gmail.com wrote:

>hey all,
>
> did c a while back, trying to get back into it. the following stub of code fails on the while(!feof(fp)) for some reason. could someone help? Thanks
>Please note that all variables here are indeed declared:


feof() does not tell you that you have read the last character. It
tells you that you have tried to read past the last character.

If the last line in the file is terminated with a \n, then feof
returns 0 and the loop will iterate one more time. In the loop, the
call to fgets will fail leaving line unchanged. You do not test for
the failure and process the last line a second time.

There are other reasons fgets can fail and you don't test for that
either.

>
> do
> {
> fgets(line,80,fp);
> tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));
> if(tmpNode == NULL)
> {
> perror("unable to allocate memory");
> intResult= -2;
> }
> sscanf(line,"%d:%s",&intVal,strVal,100);
> strcpy(tmpNode->chrName,strVal);
> tmpNode->intID = intVal;
> if(addDoubleNode(tmpNode)<0)
> {
> perror("unable to create new node...error code (-3)");
> exit(-3);
> }
> }while(!feof(fp)); //On this line the code fails.


Yes, the code fails, not the function. You are using it incorrectly.
You would do better to combine the two calls to fgets and change the
do-while to
while (fgets(line, 80, fp) {...}
and then determine why the loop terminated (end of file being normal
and anything else being an error).
>
>Thanks again


--
Remove del for email

James Kuyper 01-28-2013 04:59 AM

Re: problem with feof ?
 
On 01/27/2013 11:08 PM, mark.babli@gmail.com wrote:
> hey all,
>
> did c a while back, trying to get back into it. the following stub of code fails on the while(!feof(fp)) for some reason. could someone help? Thanks
> Please note that all variables here are indeed declared:


Keep in mind that if you do not know why something is failing, you can't
be sure what's relevant to the fact that it's failing. You should
provide a complete compilable program demonstrating your problem, not
just a few lines of code. The code where you actually observed the
failure is probably far too complicated, so you should simplify the code
as much as possible before showing it to us, removing any parts that
leave the problem intact. But after you've simplified it, it should
still be a complete compilable program - confirm this by compiling it
before you post it. It must still demonstrate the same problem you're
asking about - also confirm this before posting your message.

For a program like the following that does I/O, it's essential that you
give us an example of inputs that actually trigger the problem.

> do
> {
> fgets(line,80,fp);


You make no attempt to check whether fgets() succeeded. If it fails due
to an I/O error, the contents of 'line' are indeterminate. If it reads
the last line of the file, the end-of-file status will not be set until
until the next call to fgets(), and that call will leave the contents of
'line' unchanged, so your program will process the last line of code twice.

> tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));
> if(tmpNode == NULL)
> {
> perror("unable to allocate memory");
> intResult= -2;
> }


You check whether tmpNode is null - that's good. You produce an
appropriate message - that's good. Then you continue processing with the
null value of tmpNode. That's very bad. Since you didn't see that
message, this probably isn't the problem your seeing, but it is the
wrong way to use malloc().

> sscanf(line,"%d:%s",&intVal,strVal,100);


You make no attempt to determine whether sscanf() succeeded. It could
fail if the line is not of the specified form, in which case the
contents of intVal and strVal will be indeterminate.

If tmpNode is null, each of next two line, will have undefined behavior.
Depending upon what addDoubleNode() does with it's argument, the
behavior of that function is likely to also be undefined.


> strcpy(tmpNode->chrName,strVal);
> tmpNode->intID = intVal;
> if(addDoubleNode(tmpNode)<0)
> {
> perror("unable to create new node...error code (-3)");
> exit(-3);
> }
> }while(!feof(fp)); //On this line the code fails.


In C standard I/O, the end of a file is detected after a failed attempt
to read it, therefore, it's more appropriate to use an overall structure
like the following:

while(fgets(line, 80, fp) == line)
{
// Process line.
}
if(ferror(fp))
{
// handle I/O error
}
else
{
// End of file reached - if any special.
// handling is needed, put it here
}

While I have found many problems with your program, I can't be sure
whether any of them are relevant to the failure you observed. You should
identify what inputs were given to the program, what you expected to
happen when you gave them, and what actually happened. "the code fails"
is very nearly useless information, without details about what you mean
by "fails".
--
James Kuyper

glen herrmannsfeldt 01-28-2013 06:00 AM

Re: problem with feof ?
 
mark.babli@gmail.com wrote:
> hey all,
>
> did c a while back, trying to get back into it.
> the following stub of code fails on the while(!feof(fp)) for some
> reason. could someone help? Thanks


(snip)

> do
> {
> fgets(line,80,fp);


(snip)
> }while(!feof(fp)); //On this line the code fails.


Normally it shouldn't fail, but this all looks very suspicious.

In Pascal, and maybe some other languages, your are supposed to
check that you haven't reached EOF before reading.

In C, the EOF is only reported after a read tried and failed
(due to reaching EOF).

-- glen

Shao Miller 01-28-2013 08:27 AM

Re: problem with feof ?
 
On 1/27/2013 23:08, mark.babli@gmail.com wrote:
> hey all,
>
> did c a while back, trying to get back into it. the following stub of code fails on the while(!feof(fp)) for some reason. could someone help? Thanks
> Please note that all variables here are indeed declared:
>


Share:
- The structure type definition for 'struct dlnode'.
- The declaration of 'line'.
- The declaration of 'strVal'.

Check the return value of:
- 'fgets'
- 'sscanf'

--
- Shao Miller
--
"Thank you for the kind words; those are the kind of words I like to hear.

Cheerily," -- Richard Harter

Keith Thompson 01-28-2013 03:55 PM

Re: problem with feof ?
 
mark.babli@gmail.com writes:
> did c a while back, trying to get back into it. the following stub
> of code fails on the while(!feof(fp)) for some reason. could someone
> help? Thanks Please note that all variables here are indeed declared:
>
> do
> {
> fgets(line,80,fp);
> tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));
> if(tmpNode == NULL)
> {
> perror("unable to allocate memory");
> intResult= -2;
> }
> sscanf(line,"%d:%s",&intVal,strVal,100);
> strcpy(tmpNode->chrName,strVal);
> tmpNode->intID = intVal;
> if(addDoubleNode(tmpNode)<0)
> {
> perror("unable to create new node...error code (-3)");
> exit(-3);
> }
> }while(!feof(fp)); //On this line the code fails.


As others have pointed out, you're not telling us *how* the
code fails. There happen to be enough obvious problems with
the incomplete code you've shown us that we can help you, but in
general it's important to tell us exactly *how* it fails: what
input you gave the program, what output it produced, what you
expected it to produce, and how they differ. http://sscce.org/
has some good advice.

All C input functions return a result that tell you whether they
succeeded or not. You need to use that result, not feof(), to
decide when to termainte the loop.

An input function can fail because it encountered an end-of-file
condition, because of an I/O error, or, in some cases, because of
incorrectly formatted input (e.g., `scanf("%d", &n)` with input
"notaninteger"). Different functions indicate this in different
ways; see the documentation for each function. If you're on a
Unix-like system, `man fgets` and `man sscanf` should tell you
everything you need to know.

The feof() and ferror() functions can be used *after* an input
function has reported failure to tell you whether it was because
you reached the end of the file or because of an error. Only one
will return a true result -- which means that your program will
loop infinitely if fgets() fails due to an I/O error.

Section 12 of the excellent comp.lang.c FAQ, <http://www.c-faq.com/>,
discusses the use of C standard I/O.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

mark.babli@gmail.com 01-29-2013 01:09 AM

Re: problem with feof ?
 
you are right, I am sorry! VS immediately jumps after the first loop to an internal "file-lock" function (the code is very complex, and most of it in assembly). and I get an Error "Read Access Violation "

On Sunday, January 27, 2013 10:34:19 PM UTC-6, Joe Pfeiffer wrote:
> mark.babli@gmail.com writes:
>
>
>
> > hey all,

>
> >

>
> > did c a while back, trying to get back into it. the following stub of code fails on the while(!feof(fp)) for some reason. could someone help? Thanks

>
> > Please note that all variables here are indeed declared:

>
> >

>
> > do

>
> > {

>
> > fgets(line,80,fp);

>
> > tmpNode = (struct dlnode*)malloc(sizeof(struct dlnode));

>
> > if(tmpNode == NULL)

>
> > {

>
> > perror("unable to allocate memory");

>
> > intResult= -2;

>
> > }

>
> > sscanf(line,"%d:%s",&intVal,strVal,100);

>
> > strcpy(tmpNode->chrName,strVal);

>
> > tmpNode->intID = intVal;

>
> > if(addDoubleNode(tmpNode)<0)

>
> > {

>
> > perror("unable to create new node...error code (-3)");

>
> > exit(-3);

>
> > }

>
> > }while(!feof(fp)); //On this line the code fails.

>
> >

>
> > Thanks again

>
>
>
> What's the symptom? In what sense do you mean "fails"? segfault? some
>
> error that turns up in the debugger? laser blasts from Martians?




All times are GMT. The time now is 11:41 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.