[comp.lang.c] Turbo C, fopen

brand@janus.Berkeley.EDU (Graham Brand) (09/18/90)

I should like some help with a simple problem in Turbo C. I have a
C program which I have been running on UNIX with no problem. I am
trying to port it to Turbo C 2.0 running on my '386 under MSDOS (V3.3)
but am having a strange problem. The program opens files for appending
data using the:
	fopen(fp,filename,"a")
construction and writes the data with the usual
	fprintf(fp,"%s ...%d\n",.....)
instruction. The problem that I am having is that the line that is 
appended in the file is preceeded with a ^Z which makes the data
invisible when a type command is issued from MSDOS. I can use vi and
edit the file to remove the ^Z but don't want to have to do that every 
time. Can someone explain what is going on and propose a fix?

Thanks in advance,
Graham Brand (brand@janus.berkeley.edu)

edgincd2@mentor.cc.purdue.edu (Chris Edgington *Computer Science Major*) (09/18/90)

In article <38742@ucbvax.BERKELEY.EDU>, brand@janus.Berkeley.EDU (Graham Brand) writes:
> instruction. The problem that I am having is that the line that is 
> appended in the file is preceeded with a ^Z which makes the data
> invisible when a type command is issued from MSDOS. I can use vi and

Is the ^Z leftover from the original dos file or is it the first character of
the append data??  If it is leftover from the original file, you could you
fsetpos to set the position for writing as eof(original)-1, then it would
erase the ^Z

Chris

toma@tekgvs.LABS.TEK.COM (Tom Almy) (09/19/90)

In article <38742@ucbvax.BERKELEY.EDU> brand@janus.Berkeley.EDU writes:
>I should like some help with a simple problem in Turbo C. I have a
>C program which I have been running on UNIX with no problem. I am
>trying to port it to Turbo C 2.0 running on my '386 under MSDOS (V3.3)
>but am having a strange problem. The program opens files for appending
>data using the:

I'm sure you mean fp=fopen(filename,"a")

>	fopen(fp,filename,"a")
>construction and writes the data with the usual
>	fprintf(fp,"%s ...%d\n",.....)
>instruction. The problem that I am having is that the line that is 
>appended in the file is preceeded with a ^Z which makes the data
>invisible when a type command is issued from MSDOS.

The file undoubtedly had the ^Z character at the end when you started.
You can't delete it when opening in "a" mode because this mode forces all
writes to occur at the end of file. You will need to do something like this:

if (fp = fopen(filename,"r+") { /* file exists */
	fseek(fp,-1L,SEEK_END);	/* check last character */
	if (fgetc(fp) == 26) /* last character is a control-Z, delete it */
		fseek(fp,-1L,SEEK_END);
}
else { /* file does not already exist */
	if ((fp = fopen(filename,"w")) == NULL) {
		/* Error code for unable to create file */
	}
}


Tom Almy
toma@tekgvs.labs.tek.com
Standard Disclaimers Apply


	

darcy@druid.uucp (D'Arcy J.M. Cain) (09/20/90)

In article <14084@mentor.cc.purdue.edu> edgincd2@mentor.cc.purdue.edu (Chris Edgington *Computer Science Major*) writes:
>In article <38742@ucbvax.BERKELEY.EDU>, brand@janus.Berkeley.EDU (Graham Brand) writes:
>> instruction. The problem that I am having is that the line that is 
>> appended in the file is preceeded with a ^Z which makes the data
>> invisible when a type command is issued from MSDOS. I can use vi and
>
>Is the ^Z leftover from the original dos file or is it the first character of
>the append data??  If it is leftover from the original file, you could you
>fsetpos to set the position for writing as eof(original)-1, then it would
>erase the ^Z
>
But don't open the file in append mode.  It repositions the file pointer to
the end of the file before each write.  Also you might want to check to see
if the last character is a ^Z as well as the ones before the last.  Some of
those old programs use the CP/M method of filling a buffer with ^Zs before
writing to it so you could have as many as 128 of them.  This might work:

    long pos = 0;
    ...
    do { fseek(fp, --pos, SEEK_END) } while ((c = fgetc(fp)) == 0x1a);
    fseek(fp, ++pos, SEEK_END);

That leaves the file pointing to the first of any ^Zs or the end of file
if there are none.


-- 
D'Arcy J.M. Cain (darcy@druid)     |
D'Arcy Cain Consulting             |   MS-DOS:  The Andrew Dice Clay
West Hill, Ontario, Canada         |   of operating systems.
+ 416 281 6094                     |

otto@tukki.jyu.fi (Otto J. Makela) (09/20/90)

In article <1990Sep20.014132.29461@druid.uucp> darcy@druid.uucp (D'Arcy J.M. Cain) writes:
[how to position file to skip trailing ^Z's on brain-dead CP/M -like systems]
       long pos = 0;
       ...
       do { fseek(fp, --pos, SEEK_END) } while ((c = fgetc(fp)) == 0x1a);
       fseek(fp, ++pos, SEEK_END);

Be careful with this stuff.  Because you reseek as the last thing you do,
this will work.  I have seen several C librarys which get confused when
you seek, read and then write a stream (probably some buffering messing
things up).  Or is this perhaps (horror of horrors) standard behaviour ?
I wrote code like:
	fseek(fp, -1L, SEEK_END);
	while(fgetc(fp)==0x1A) fseek(fp, -2L, SEEK_CUR);
At this point I assumed the file would be positioned correctly.  Didn't
work on DOS, didn't work on BSD Unix.  I had to add:
	fseek(fp, 0L, SEEK_CUR);

But you of course were aware of this.
--
* * * Otto J. Makela <otto@jyu.fi> * * * * * * * * * * * * * * * * * * * * *
* Phone: +358 41 613 847, BBS: +358 41 211 562 (CCITT, Bell 2400/1200/300) *
* Mail: Kauppakatu 1 B 18, SF-40100 Jyvaskyla, Finland, EUROPE             *
* * * Computers Rule 01001111 01001011 * * * * * * * * * * * * * * * * * * *

karl@haddock.ima.isc.com (Karl Heuer) (09/22/90)

In article <OTTO.90Sep20180445@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes:
>Be careful with this stuff...  I have seen several C librarys which get
>confused when you seek, read and then write a stream (probably some buffering
>messing things up).  Or is this perhaps (horror of horrors) standard
>behaviour ?

Yes.  You can't switch between reading and writing unless you sync the stream
first; fseek() is one way to do so.  See 4.9.5.3 of the ANS.

Karl W. Z. Heuer (karl@kelp.ima.isc.com or ima!kelp!karl), The Walking Lint

brand@janus.Berkeley.EDU (Graham Brand) (09/27/90)

Dear All,

	Thanks to the 6 or so of you who replied. No one respondent in
particular was completely correct; the solution turned out to be a
combination of things. Most people mentioned the history of CP/M and ^Z
and so suggested using the fseek(fp,-1L,SEEK_END) approach. A couple
suggested using the "b" access_mode option as in 
fp=fopen("filename","rb+"). The solution that worked uses both of these.
I must admit that I am not too sure why, but having spent more time on
this simple problem than I had intended, I shan't worry about it too 
much.

	Before I lay the problem to rest, though, there is one peculiar
aspect that I have not resolved. It is the fact that, before I added the
fixes to the program, even if I ensured that the file did **NOT** have 
a ^Z eof termination when I started, my program would prepend a ^Z to 
any line of text that was added to the end of the file. The only file
operations that were done in the program were fopen() and fprintf()? 
Where was the ^Z coming from and which of the changes, fseek(.,-1L,.) or
fopen(.,"b"), cured it?

Thanks for all your help,
-Graham

mgphl@msa3b.UUCP (Michael Phillips) (09/29/90)

brand@janus.Berkeley.EDU (Graham Brand) writes:

>...
>any line of text that was added to the end of the file. The only file
>operations that were done in the program were fopen() and fprintf()? 
>Where was the ^Z coming from and which of the changes, fseek(.,-1L,.) or
>fopen(.,"b"), cured it?

>Thanks for all your help,
>-Graham
 
Graham, Absolutely, positively, it was the fopen(.,"b") that cured your ^Z
problem.  Since ^Z is the "end-of-file" marker for _TEXT_ files, anytime a
file is opened as _text_ ("t", the usual default), and the file is updated
in some way, it should have a ^Z appended to the end.   Now I think that
the ^Z is basically useless, but it is the way DOS defines things so I live
with it.

Michael
*-----------------------------------------------------------------------*
D&B Software Atlnata, GA - "Constants aren't and Variables don't"