append mode ("a") query

Derek R. Foster dfoster at jarthur.Claremont.EDU
Thu Feb 15 09:10:20 AEST 1990


In article <4983.25d7e9db at uwovax.uwo.ca> chet at uwovax.uwo.ca writes:
>I know I'll be embarrassed because of this, but would someone please
>tell me why program A below, when executed twice contains twenty lines
>(i.e. the 2nd ten lines are inserted before the EOF mark), but program B
>positions its appends after the EOF mark (so that they don't appear when
>the file is typed out)? And what I can do to fix B. This happens on
>Turbo C and Small C (2.2), and I presume on every C compiler.
>[program text follows]

note: I attempted to mail this directly, but my host computer doesn't seem
to believe uwovax.uwo.ca exists. I think it's useful enough information
to post to the net, so I have. 

I don't know if this is a solution or not: just a suggestion of something
that might be related to your problem.
I don't see any reason why your two programs would definitely act 
differently. However,
I do see a POSSIBLE reason why program B might act as described, 
along with a possible reason for A's working fine.

The EOF marker character (ctrl-z on my system) is only meaningful in 
the case of text files.

In a binary file, always adding text before an EOF character would
be clearly inappropriate, since the character might actually be data in
the file.

Therefore, the C routines, if they do detection like this at all (which
they may not - if so, see option #2 below.) must
be able to tell which kind of file this is in order to tell if they should
consider the EOF character to be the end of the file, or if they should
judge file size by the "file length" field in the disk's directory entry.
(which contains the ENTIRE length of the file, INCLUDING any EOF characters
in the file as well as anything that may follow them.)

possible solution 1:
Try opening your file explicitly in text mode ie. 
  stream = fopen(filename, "at");
if your C compiler is "smart" enough to know the difference, this may solve
your problem. My logic here is that something in other routines
in the program may have messed with the value of the
_fmode system variable, which affects the default mode (text or binary) that
the file was opened in. This would explain the results you describe. (if file
A was opened in text mode, but file B was opened in binary mode.) 
If you state the mode explicitly, then you have at least removed this as a
possible source of error.

possible solution 2: "how do I get program B to work correctly"
If that doesn't work, try using the fseek function to
"back up" the stream pointer to before the EOF character.
(assuming, of course, that there is one - using an actual character
to mark the end of a text file has sort of gone out of style nowadays. 
Many editors don't automatically put one there anymore. Watch out for this.)

/* WARNING : this code fragment assumes that the file in question
   a) has at least one byte in it.
   b) has no EOF characters occurring before the actual end-of-file
      (as reported by the disk directory entry)
   c) has an EOF character as the last byte in the file.
   if you aren't SURE of any of these assumptions, you may have to include
   additional code and/or file processing.
*/
  stream = fopen(filename, "at");
  fseek(stream,-1,SEEK_END); /* position the file pointer one before the
                                end-of-file, so that the next character
                                you write will overwrite the last character
                                in the file */

My Turbo C manual states that fseek is "available on UNIX systems" so this
should be fairly portable.

Hope this helps!

Derek Riippa Foster



More information about the Comp.lang.c mailing list