Newbie fgets problem

G

g.managoli

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
FILE *fptr;
char* buffer = malloc(20);
buffer[0] = '1';

if(argc < 2)
{
fptr = fopen("file.txt", "r");
}
else
{
fptr = fopen(argv[1], "r");
}


if(!fptr)
{
printf("File did not open\n");

return 0;
}


while(fptr) /* Does not seem to work */
{
fgets(buffer, 20, fptr);

printf("Read string: %s\n", buffer);

getchar();
}

return 1;


}

Hi,
I have a problem with the while loop where it checks whether the file
pointer has reached the end of file. This does not seem to work and the
loop executes infinitely. What should be check-clause in the loop?

Also, I have read comments on this group about replacing 'scanf' with
'fgets' and 'sscanf'. Could someone tell me how to do this?
If I am repeating a question that is already in FAQ, kindly point to
it.

Any help is appreciated,
Anjali.
 
M

Mike Deskevich

fptr will always point to the file. it doesn't magically become null
at the end of file. the proper way

FILE* fptr=fopen(...);
while( fptr&&!feof(fptr))
{
/*do stuff*/
}
if (fptr) fclose(fptr);
 
S

Steve Graegert

Yes, the loop runs infinitely because fptr is a pointer to a FILE
structure and evaluates true unless becomes NULL all of a sudden which
is _very_ unlikely.

The fgets function returns NULL when the end of file is reached or an NL
character found on input. Therefore you should test for the result
returned by fgets. For example

while ((fgets(buffer, sizeof(buffer), fptr)) != NULL) {
printf("Read string: %s\n", buffer);
getchar();
}

This will read up to one line from the terminal (until the NL-character
is encountered) or until the EOF indicator is encountered.

BTW: to avoid writing lots of code you can combine your library and
system calls with simple error checking by using popular constructs like

if ((fp = fopen(argv[1], "r")) == NULL) {
printf("Could not open file: %s\n", argv[1]);
exit(-1);
}

One disadvantage of using scanf is the fact that it usually interprets a
blank as the end of a particular input value and may return before
having read the entire line or file.

\Steve
 
R

Robert Harris

Steve said:
Yes, the loop runs infinitely because fptr is a pointer to a FILE
structure and evaluates true unless becomes NULL all of a sudden which
is _very_ unlikely.

The fgets function returns NULL when the end of file is reached or an NL
character found on input.
Not true. man fgets will put you right.
Robert
 
S

Steve Graegert

Robert said:
Not true. man fgets will put you right.

This is what man fgets(3) says:

fgetc() reads the next character from stream and returns
it as an unsigned char cast to an int, or EOF on end of
file or error.

...

gets() and fgets() return s on success, and NULL on error
or when end of file occurs while no characters have been
read.


On a POSIX-compliant enviroment fgets works as defined:

The fgets() function shall read bytes from stream into the
array pointed to by s, until n-1 bytes are read, or a
<newline> is read and transferred to s, or an end-of-file
condition is encountered. The string is then terminated with
a null byte.

RETURN VALUE

Upon successful completion, fgets() shall return s. If the
stream is at end-of-file, the end-of-file indicator for the
stream shall be set and fgets() shall return a null pointer.
If a read error occurs, the error indicator for the stream
shall be set, fgets() shall return a null pointer,
and shall set errno to indicate the error.

This exactly how it works on all plaforms I worked with (Linux, Solarism
Tru64Unix). So please enlighten me and and tell us how it really works.

\Steve
 
C

CBFalconer

Robert said:
Not true. man fgets will put you right.

You are wrong and Steve is partially right. fgets returns NULL on
any error or EOF, else non-NULL. It has nothing to do with finding
any '\n's.
 
R

Robert Harris

Steve said:
This is what man fgets(3) says:

fgetc() reads the next character from stream and returns
it as an unsigned char cast to an int, or EOF on end of
file or error.

...

gets() and fgets() return s on success, and NULL on error
or when end of file occurs while no characters have been
read.


On a POSIX-compliant enviroment fgets works as defined:

The fgets() function shall read bytes from stream into the
array pointed to by s, until n-1 bytes are read, or a
<newline> is read and transferred to s, or an end-of-file
condition is encountered. The string is then terminated with
a null byte.

RETURN VALUE

Upon successful completion, fgets() shall return s. If the
stream is at end-of-file, the end-of-file indicator for the
stream shall be set and fgets() shall return a null pointer.
If a read error occurs, the error indicator for the stream
shall be set, fgets() shall return a null pointer,
and shall set errno to indicate the error.

This exactly how it works on all plaforms I worked with (Linux, Solarism
Tru64Unix). So please enlighten me and and tell us how it really works.

\Steve
Yes, that is exactly how it works. And fgets does not return NULL if it
encounters a NL character on input.
 
O

Old Wolf

Mike Deskevich said:
fptr will always point to the file. it doesn't magically become null
at the end of file. the proper way

FILE* fptr=fopen(...);
while( fptr&&!feof(fptr))
{
/*do stuff*/
}
if (fptr) fclose(fptr);

This is also the wrong way.
You just admitted that fptr doesn't become NULL so why test for it
every iteration of the loop?
Also, feof() does not return TRUE until after a read has failed.
So if your "do stuff" includes reading something from the file
without checking for success, then your code will misbehave on
the final iteration.

The right way is to check your read operation for success or
failure. For example:

while ( fgets(.......) )

or

while ( EOF != (i = fgetc(fptr)) )

or test inside the loop and 'break' on failure. Etc etc.
 

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

Help with C negative indexes 2
Using fgets 1
fgets problem 23
understanding fgets() 11
Scanf is being prioritized over printf ? 1
Proper fgets 9
Replacing fgets Problem solved. 3
fgets 6

Members online

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,011
Latest member
AjaUqq1950

Latest Threads

Top