Can the current file position indicator ever be greater the actual file size?

A

Andrew

Hello,

Is it possible for a file position indicator of an input stream to be
greater than the size of a file? And if so could this cause fgetc to
somehow write to the file? For example is it possible to continually
call fgetc past the size of the file and cause some type of undefined
behavior? Thanks
 
N

nrk

Andrew said:
Hello,

Is it possible for a file position indicator of an input stream to be
greater than the size of a file?

Size of a file is vague (as in there's no such thing in standard C). It
is not possible to advance the file position indicator once the end of
file indicator is set.
And if so could this cause fgetc to
somehow write to the file? For example is it possible to continually
call fgetc past the size of the file and cause some type of undefined
behavior? Thanks

A conforming implementation of fgetc will advance the file position
indicator only if the end of file indicator is not set, and it seems
unlikely that it will modify the underlying stream. Hence, not possible.

-nrk.
 
A

Andrew

Hello,

Is it possible for a file position indicator of an input stream to be
greater than the size of a file? And if so could this cause fgetc to
somehow write to the file? For example is it possible to continually
call fgetc past the size of the file and cause some type of undefined
behavior? Thanks

Sorry, Let me try to re-phrase this with a simple example. The
following code writes the letter A and an additional 10 bytes (1 for
each call to fgetc) to the output file . I am wondering why this
happens and if there is a way I can avoid it. I don't believe fflush
is suppose to be used on this type of stream? Although, I tried
fflush(of) and it worked, but I suspect it would have wiped out any
previous information which the file contained that I might want to
preserve. Thanks for any advice.

#include <stdio.h>

int main() {

FILE *of;
int i;

if((of = fopen("c:\\problem.txt", "w")) == NULL) {
if((of = fopen("c:\\problem.txt", "r+")) == NULL) {
printf("\nFile Error");
}
}

/* Without a fputc call before the loop the problem does
not exist */

fputc(65,of);

/* tried fflush(of) here but I think this is undefined?
and it seems to clear any previous contents
stored before program execution */

/* 10 can be replaced with any number larger than the
input file size */
for(i = 0; i < 10; i++)
fgetc(of);

fclose(of);

return 0;

}
 
R

Richard Heathfield

Andrew said:
Sorry, Let me try to re-phrase this with a simple example. The
following code writes the letter A and an additional 10 bytes (1 for
each call to fgetc) to the output file . I am wondering why this
happens and if there is a way I can avoid it. I don't believe fflush
is suppose to be used on this type of stream? Although, I tried
fflush(of) and it worked, but I suspect it would have wiped out any
previous information which the file contained that I might want to
preserve. Thanks for any advice.

#include <stdio.h>

int main() {

FILE *of;
int i;

if((of = fopen("c:\\problem.txt", "w")) == NULL) {
if((of = fopen("c:\\problem.txt", "r+")) == NULL) {

This looks a bit scary, but it basically says "if I can't create it, I want
to open it read-write instead". If that's what you want, then fair enough.
printf("\nFile Error");
}
}

/* Without a fputc call before the loop the problem does
not exist */

fputc(65,of);

This doesn't write 'A', by the way - it writes whatever character happens to
have the value 65 on the system you're running it on. (Let me guess - 'A'
on your system, right? But on, say, an IBM mainframe, you'd get a different
result.)

fputc('A', of); conveys your intent more clearly /and/ is portable.
/* tried fflush(of) here but I think this is undefined?

No, you're fine with fflush() on streams open for output or update.
and it seems to clear any previous contents
stored before program execution */

That's not fflush()'s fault. That's your "w" mode talking (remember those
fopen() calls above?). Swap it around with your "r+".
/* 10 can be replaced with any number larger than the
input file size */
for(i = 0; i < 10; i++)
fgetc(of);

If the file was successfully created ("w" mode), there's nothing to read, is
there? So fgetc() will return EOF, to indicate that it couldn't fulfil your
request. I note that your program is not checking the return value of
fgetc. If you add a check, you will find that fgetc is returning EOF on
each call.
 
J

Jack Klein

Sorry, Let me try to re-phrase this with a simple example. The
following code writes the letter A and an additional 10 bytes (1 for
each call to fgetc) to the output file . I am wondering why this
happens and if there is a way I can avoid it. I don't believe fflush
is suppose to be used on this type of stream? Although, I tried
fflush(of) and it worked, but I suspect it would have wiped out any
previous information which the file contained that I might want to
preserve. Thanks for any advice.

#include <stdio.h>

int main() {

FILE *of;
int i;

if((of = fopen("c:\\problem.txt", "w")) == NULL) {
if((of = fopen("c:\\problem.txt", "r+")) == NULL) {
printf("\nFile Error");
}
}

/* Without a fputc call before the loop the problem does
not exist */

fputc(65,of);

/* tried fflush(of) here but I think this is undefined?
and it seems to clear any previous contents
stored before program execution */

/* 10 can be replaced with any number larger than the
input file size */
for(i = 0; i < 10; i++)
fgetc(of);

fclose(of);

return 0;

}

You are breaking a rule of the C library, and so you are causing
undefined behavior:

"When a file is opened with update mode ('+' as the second or third
character in the above list of mode argument values), both input and
output may be performed on the associated stream. However, output
shall not be directly followed by input without an intervening call to
the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by
output without an intervening call to a file positioning function,
unless the input operation encounters endof-file."

When you use fputc() and then use fgetc() without calling a
file-seeking function in between, you are violating a "shall" clause
outside of a constraint section. The result is undefined behavior
which can be anything, as far as C is concerned, including putting
things in your file that you do not want.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
J

Jack Klein

Sorry, Let me try to re-phrase this with a simple example. The
following code writes the letter A and an additional 10 bytes (1 for
each call to fgetc) to the output file . I am wondering why this
happens and if there is a way I can avoid it. I don't believe fflush
is suppose to be used on this type of stream? Although, I tried
fflush(of) and it worked, but I suspect it would have wiped out any
previous information which the file contained that I might want to
preserve. Thanks for any advice.

#include <stdio.h>

int main() {

FILE *of;
int i;

if((of = fopen("c:\\problem.txt", "w")) == NULL) {
if((of = fopen("c:\\problem.txt", "r+")) == NULL) {
printf("\nFile Error");
}
}

/* Without a fputc call before the loop the problem does
not exist */

fputc(65,of);

/* tried fflush(of) here but I think this is undefined?
and it seems to clear any previous contents
stored before program execution */

/* 10 can be replaced with any number larger than the
input file size */
for(i = 0; i < 10; i++)
fgetc(of);

fclose(of);

return 0;

}

You are breaking a rule of the C library, and so you are causing
undefined behavior:

"When a file is opened with update mode ('+' as the second or third
character in the above list of mode argument values), both input and
output may be performed on the associated stream. However, output
shall not be directly followed by input without an intervening call to
the fflush function or to a file positioning function (fseek,
fsetpos, or rewind), and input shall not be directly followed by
output without an intervening call to a file positioning function,
unless the input operation encounters endof-file."

When you use fputc() and then use fgetc() without calling a
file-seeking function in between, you are violating a "shall" clause
outside of a constraint section. The result is undefined behavior
which can be anything, as far as C is concerned, including putting
things in your file that you do not want.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
 
A

Avinash

Hello,

Is it possible for a file position indicator of an input stream to be
greater than the size of a file? And if so could this cause fgetc to
somehow write to the file? For example is it possible to continually
call fgetc past the size of the file and cause some type of undefined
behavior? Thanks



If the end-of-file indicator for the input stream pointed to by stream
is not set and a next byte is present, the fgetc() function shall
obtain the next byte as an unsigned char converted to an int, from the
input stream pointed to by stream, and advance the associated file
position indicator for the stream (if defined). Since fgetc() operates
on bytes, reading a character consisting of multiple bytes (or "a
multi-byte character") may require multiple calls to fgetc().
 
A

Andrew

Thanks everyone for your advice. I was not aware of the consequences
involved with omitting a file seeking call in between these types of
file operations. I apologize for posting a question that could have
easily found out from further reading, but I think I had been looking
in the wrong direction for the root of the problem. This advice along
with clarification on the open file mode I was using helped alot.
Thanks again.
 

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

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,536
Members
45,007
Latest member
obedient dusk

Latest Threads

Top