By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,903 Members | 1,670 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,903 IT Pros & Developers. It's quick & easy.

File Read help reqd

P: n/a
Hello All,

Can any one help me in this file read problem.

#include <stdio.h>

int main()
{
FILE* fp = fopen("TITLE.mx2","rb");

char h[100];

while(fscanf(fp,"%[^\r\n]",h) != EOF)
{
fprintf(stdout,"%s",h);
if((fscanf(fp,"%[\r\n]",h) == EOF)) //dummy
break;
}
fclose(fp);
return 0;

}

it goes into an infinite loop.

Am i eating up the EOF?

here while(fscanf(fp,"%[^\r\n]",h) != EOF)?

how to avoid it?

Thanks in advance.

Regards,
Naren.

Nov 14 '05 #1
Share this Question
Share on Google+
7 Replies


P: n/a
Naren wrote:

#include <stdio.h>
int main()
{
FILE* fp = fopen("TITLE.mx2","rb");
char h[100];

while(fscanf(fp,"%[^\r\n]",h) != EOF)


fscanf can never return EOF. Try reading its definition.

--
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare
Nov 14 '05 #2

P: n/a
CBFalconer wrote:
Naren wrote:

#include <stdio.h>
int main()
{
FILE* fp = fopen("TITLE.mx2","rb");
char h[100];

while(fscanf(fp,"%[^\r\n]",h) != EOF)


fscanf can never return EOF. Try reading its definition.


According to my copy of the Standard:
7.19.6.2p16:

The fscanf function returns the value of the macro EOF if an input
failure occurs
before any conversion.

Am I missing something?

Robert Gamble

Nov 14 '05 #3

P: n/a
In article <11**********************@g47g2000cwa.googlegroups .com>
Naren <na******************@gmail.com> wrote:
[snippage, and minor vertical compression]
FILE* fp = fopen("TITLE.mx2","rb");
char h[100];

while(fscanf(fp,"%[^\r\n]",h) != EOF) {
fprintf(stdout,"%s",h);
if((fscanf(fp,"%[\r\n]",h) == EOF)) //dummy
break;
}
... goes into an infinite loop.


One possibility is that the fopen() has failed and fp==NULL and
the undefined behavior of calling fscanf() with this NULL is
that it does nothing other than return a value not equal to -1.
For instance, perhaps your fscanf() happens to return 42 when
called with NULL (and read no data, or at least do nothing
visibly harmful). This could easily result in an infinite
loop.

Another possibility is that one of the fscanf() calls overruns the
buffer h[], i.e., there are more than 99 non-\r non-\n characters
in sequence at some point, or there are more than 99 \r-or-\n
characters in sequence at some other point. This would store
more than 100 "char"s in the 100-char array, leading to undefined
behavior, which could also result in an infinite loop.

It also seems very odd to open with "rb" and then use fgets(),
since fgets() is a "text-file-oriented" operation (text files are
composed of "lines", while binary files contain arbitrary binary
data not necessarily composed of lines). But this in and of
itself should not result in an infinite loop.

Other than these issues, the code *should* not loop forever. The
first fscanf() directive -- a "%[" -- matches one or more non-\r
non-\n characters, or fails with either an input or a matching
failure. In most cases (non-blank first text line), it will succeed,
and read-and-convert the non-\r-or-\n characters, storing them in
h[].

If the file begins with a sequence of \r-or-\n characters, the
first fscanf() performed will fail with a matching failure and
return 0, leaving garbage in the array h[]. The fprintf() to stdout
would then technically have undefined behavior, which theoretically
could result in an infinite loop; but in practical terms, on the
computer you are using (the one I see in my crystal ball :-) ),
you would just get either garbage output, or no output at all, from
that fprintf().

Having either succeeded or failed with a matching failure, fscanf()
will then return either 1 or 0 (respectively). You ignore this
distinction in return values -- which is almost always a bug, and
is indeed a bug in this case -- and go on to print the contents of
the array (possibly garbage).

You then call fscanf() again, using another %[ directive, but this
one says "read and convert at least one, and as many as possible,
\r or \n characters". Since the previous conversion will have read
and converted everything that is not a \r or \n, the only possible
character in the stream at this point is \r or \n. Thus, if there
are any characters to read at all, the %[ directive will definitely
succeed. The only other possibility is that getc(fp) will return
EOF (due to input error or end-of-file), rather than returning a
'\r' or '\n' character; in that case, the fscanf() call itself will
return EOF, and the "break" will terminate the loop. Since the
loop does not terminate, we can assume that fscanf() does find at
least one \r or \n, and writes them into the array h[]. (Thus, if
there are 37 '\r' characters followed by 3 '\n's followed by 9
'\r's followed by 'x' or EOF, h[] will have 37+3+9+1 = 50 bytes
written into it.) The fscanf() call will then return 1 -- the
only possible return values are EOF and 1, in this case. Hence
the test fscanf(...)==EOF is sufficient, unlike the initial one in
the while loop.

If the fscanf() does return 1, we know that the fscanf() stopped
at either a non-\r non-\n character, or it encountered EOF. Thus,
subsequent trips through the while loop's test will have a return
value from fscanf() of either EOF or 1. Only the very first
fscanf() performed can return 0 (when the file begins with a
'\r' or '\n' character).

All of this may leave the original poster with the question of what
he *should* code, instead of the above; but no one can really answer
that, as he has not expressed a goal, merely a question about the
loop. I can make a guess here (that the goal is to remove all
'\n' and/or '\r' characters from a binary file), but it is just a
guess, and it seems a little unlikely.
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Nov 14 '05 #4

P: n/a
Robert Gamble wrote:
CBFalconer wrote:
.... snip ...
fscanf can never return EOF. Try reading its definition.


According to my copy of the Standard:
7.19.6.2p16:

The fscanf function returns the value of the macro EOF if an input
failure occurs before any conversion.

Am I missing something?


No, but I am. Thanks for the correction.

--
"I conclude that there are two ways of constructing a software
design: One way is to make it so simple that there are obviously
no deficiencies and the other way is to make it so complicated
that there are no obvious deficiencies." -- C. A. R. Hoare

Nov 14 '05 #5

P: n/a
El Thu, 02 Jun 2005 10:19:36 GMT, CBFalconer escribió:
According to my copy of the Standard:
7.19.6.2p16:

The fscanf function returns the value of the macro EOF if an input
failure occurs before any conversion.

Am I missing something?


No, but I am. Thanks for the correction.


Not at all. It says *input failure* needed to return EOF. So, if a conversion
occurs ([^\r\n]) with no input failure, fscanf will not return EOF and
thus the while will be a forever loop. Please correct me if i'm wrong.

Greetings
--
Luis Alberto Giménez
JabberID: Si*******@bulmalug.net
GnuPG ID: 0x3BAABDE1
Nov 14 '05 #6

P: n/a
In article <m5**********@127.0.0.1>,
Alberto =?iso-8859-1?Q?Gim=E9nez?= <al****@teleline.es> wrote:
El Thu, 02 Jun 2005 10:19:36 GMT, CBFalconer escribió:
According to my copy of the Standard:
7.19.6.2p16: The fscanf function returns the value of the macro EOF if an input
failure occurs before any conversion.
Not at all. It says *input failure* needed to return EOF. So, if a conversion
occurs ([^\r\n]) with no input failure, fscanf will not return EOF and
thus the while will be a forever loop. Please correct me if i'm wrong.


No, if a conversion occurs then at least one character will be removed
from the input stream -- and with that particular format, all the
characters until EOF or the first \r or \n will be removed from the
input stream.

Thus after the execution of the fscanf() that is the condition of the
while() loop, if a conversion occured then input has been removed and
one is positioned at an EOF or \r or \n. Then one encounters the
second fscanf() which is the condition of the "if" statement.

If one was at a \r or \n then the fscanf() at the "if" will remove all
the \r and \n that await in sequence, either leaving one at EOF or
at a character which is not \r or \n and looping back.

Inductively, this will repeat until one or the other of the fscanf()
encounters EOF; at that point, the next fscanf() *will* return EOF
and either the 'break' will take effect or the while() condition will
become false and the loop will end.
There is the case where the input starts out positioned at \r or \n
but there are characters there. In that situation, the conversion count
will be 0 for the while()'s fscanf(), but 0 != EOF so the loop body
will be executed and the inner fscanf() will consume the \r \n sequence
leading back to the case solved above.
The next bit you need to know for this to work is that fscanf()
*defines* that when EOF is reached with no conversion having taken
place, that an "input failure" is returned. And then, as was quoted,
that "input failure" is signaled by the value EOF being returned.

For more certainty, examine the example at the end of the C89
description of fscanf(), and notice that it -specifically- has
"count" becoming EOF at the end of the input stream.

--
Ceci, ce n'est pas une idée.
Nov 14 '05 #7

P: n/a
Hello All,

I am extremely sorry for the delay,
Thanks for answers.

I have thing to add if i just added

while(!feof(fp) && fscanf(fp,"%[^\r\n]",h) != EOF)

It breaks the infinte loop and it works fine. Is there anything wrong
in my usage?

Thanks and Regards,
Naren.

Nov 14 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.