Naren said:
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.