[comp.os.msdos.programmer] Turbo C and ^Z's

otto@tukki.jyu.fi (Otto J. Makela) (01/03/91)

In a fit of desperation, I wrote the following code to get rid of trailing
SUB's (^Z's, 0x1A) from MeSsy-DOS files, to make porting programs from Unix
easier... what am I doing wrong ?  Or is it the compiler (I tried compiling
this with an ancient Turbo C 2.0) ?  I've made similar code to work on Manx
Aztec C86 4.10d (a nice compiler, but sadly out of date).
--
#include	<stdio.h>
#include	<fcntl.h>

/*
**	MeSsy-DOS kludge for fopen-append
*/
FILE *fopena(filename)
char *filename;	{
	FILE *f;

	if(f=fopen(filename,"a+b"))	{
		fseek(f,-1L,SEEK_END);
		while(fgetc(f)==0x1A) fseek(f,-2L,SEEK_CUR);
			/* This is needed to clear stdio buffering */
		fseek(f,ftell(f),SEEK_SET);
			/* Then set text mode on the stream */
		setmode(fileno(f),O_TEXT);
	}
	return f;
}

main(argc,argv)
int argc;
char *argv[];	{
	FILE *f;

	if(argc<2)
		fprintf(stderr,"usage: %s file_to_append_to\n",*argv);
	else if(f=fopena(argv[1]))	{
		fprintf(f,"This is the appended text.\n");
		fclose(f);
	} else
		fprintf(stderr,"%s: could not open %s for append\n",
			*argv,argv[1]);
}
--
   /* * * Otto J. Makela <otto@jyu.fi> * * * * * * * * * * * * * * * * * * */
  /* Phone: +358 41 613 847, BBS: +358 41 211 562 (CCITT, Bell 24/12/300) */
 /* Mail: Kauppakatu 1 B 18, SF-40100 Jyvaskyla, Finland, EUROPE         */
/* * * Computers Rule 01001111 01001011 * * * * * * * * * * * * * * * * */

wirzeniu@cs.Helsinki.FI (Lars Wirzenius) (01/04/91)

In article <OTTO.91Jan3125711@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes:
>	if(f=fopen(filename,"a+b"))	{

"a" means that all writes happen at the end of the file, use "r+b" 
instead.
--
Lars Wirzenius    wirzeniu@cs.helsinki.fi    wirzenius@cc.helsinki.fi

otto@tukki.jyu.fi (Otto J. Makela) (01/04/91)

In article <10251@hydra.Helsinki.FI> wirzeniu@cs.Helsinki.FI (Lars Wirzenius) writes:
   In article <OTTO.91Jan3125711@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes:
   >	if(f=fopen(filename,"a+b"))	{

   "a" means that all writes happen at the end of the file, use "r+b" instead.

ALL WRITES ?  Come on, the first thing I do after that is to seek the file...
I'd like to point out I can't use "r+b", 'cause it'll fail if the file does
not exist beforehand.
--
   /* * * Otto J. Makela <otto@jyu.fi> * * * * * * * * * * * * * * * * * * */
  /* Phone: +358 41 613 847, BBS: +358 41 211 562 (CCITT, Bell 24/12/300) */
 /* Mail: Kauppakatu 1 B 18, SF-40100 Jyvaskyla, Finland, EUROPE         */
/* * * Computers Rule 01001111 01001011 * * * * * * * * * * * * * * * * */

marwk@levels.sait.edu.au (01/04/91)

In article <OTTO.91Jan3125711@tukki.jyu.fi>, otto@tukki.jyu.fi (Otto J. Makela) writes:
> In a fit of desperation, I wrote the following code to get rid of trailing
> SUB's (^Z's, 0x1A) from MeSsy-DOS files, to make porting programs from Unix
> easier... what am I doing wrong ?  Or is it the compiler (I tried compiling
> this with an ancient Turbo C 2.0) ?  I've made similar code to work on Manx
> Aztec C86 4.10d (a nice compiler, but sadly out of date).
> --
> #include      <stdio.h>
> #include      <fcntl.h>

The method is to use the method of handles instead of streams.
Use open (in binary mode), read, write, close.
Read the reference manual on these.

You could use flen = filelength(input handle) and read all of the data into
a buffer but then you must be certain in advance that the last byte is the
EOF marker (1A) and not data.

Ray

karl@ima.isc.com (Karl Heuer) (01/05/91)

In <OTTO.91Jan4115449@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes:
>In <10251@hydra.Helsinki.FI> wirzeniu@cs.Helsinki.FI (Lars Wirzenius) writes:
>>"a" means that all writes happen at the end of the file, use "r+b" instead.
>
>ALL WRITES ?  Come on, the first thing I do after that is to seek the file...

Lars is correct.  On a file opened in append-mode, fseek() is only useful for
reading.  (Though some historical implementations implemented append-mode with
an initial seek-to-end only, this is not acceptable in ANSI C.)

>I'd like to point out I can't use "r+b", 'cause it'll fail if the file does
>not exist beforehand.

Then use "w+b".

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

ralf+@cs.cmu.edu (Ralf Brown) (01/05/91)

In article <OTTO.91Jan4115449@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes:
}In article <10251@hydra.Helsinki.FI> wirzeniu@cs.Helsinki.FI (Lars Wirzenius) writes:
}   In article <OTTO.91Jan3125711@tukki.jyu.fi> otto@tukki.jyu.fi (Otto J. Makela) writes:
}   >	if(f=fopen(filename,"a+b"))	{
}   "a" means that all writes happen at the end of the file, use "r+b" instead
}ALL WRITES ?  Come on, the first thing I do after that is to seek the file...

That's correct.  The Turbo C standard library seeks to the end of the file
every time you make a write call to a file opened in Append mode.
--
{backbone}!cs.cmu.edu!ralf  ARPA: RALF@CS.CMU.EDU   FIDO: Ralf Brown 1:129/3.1
BITnet: RALF%CS.CMU.EDU@CMUCCVMA   AT&Tnet: (412)268-3053 (school)   FAX: ask
DISCLAIMER?  Did  | Everything is funny as long as it is happening to
I claim something?| someone else.  --Will Rogers

otto@tukki.jyu.fi (Otto J. Makela) (01/07/91)

In article <1991Jan04.173903.20643@dirtydog.ima.isc.com> karl@ima.isc.com (Karl Heuer) writes:
[...]
   Lars is correct.  On a file opened in append-mode, fseek() is only useful
   for reading.  (Though some historical implementations implemented append-
   mode with an initial seek-to-end only, this is not acceptable in ANSI C.)

Yes.  Confirm.  Affirmative.  Now that I've gone thru it, this seems to be
how it works.  I didn't realize ANSI decided to break compatibility with Unix
in such a radical way...

   >I'd like to point out I can't use "r+b", 'cause it'll fail if the file does
   >not exist beforehand.

   Then use "w+b".

Can't do that either, 'cause I don't want to kill the file.  I need both.
Here is the fixed code, if someone finds it useful...
--
#include	<stdio.h>
#include	<fcntl.h>

#ifdef	UNIX
#define	fopena(filename)	fopen(filename,"a")
#else

/*
**	MeSsy-DOS kludge to replace fopen(filename,"at")
*/
FILE *fopena(filename)
char *filename;	{
	FILE *f;

	if(f=fopen(filename,"r+b"))	{
		fseek(f,-1L,SEEK_END);
		while(fgetc(f)==0x1A) fseek(f,-2L,SEEK_CUR);
			/* This is needed to clear stdio buffering */
		fseek(f,ftell(f),SEEK_SET);
		setmode(fileno(f),O_TEXT);
	} else
		f=fopen(filename,"wt");
	return f;
}
#endif

/*
**	Test main program
*/
main(argc,argv)
int argc;
char *argv[];	{
	FILE *f;

	if(argc<2)
		fprintf(stderr,"usage: %s file_to_append_to\n",*argv);
	else if(f=fopena(argv[1]))	{
		fprintf(f,"This is the appended text.\n");
		fclose(f);
	} else
		fprintf(stderr,"%s: could not open %s for append\n",
			*argv,argv[1]);
}
--
   /* * * Otto J. Makela <otto@jyu.fi> * * * * * * * * * * * * * * * * * * */
  /* Phone: +358 41 613 847, BBS: +358 41 211 562 (CCITT, Bell 24/12/300) */
 /* Mail: Kauppakatu 1 B 18, SF-40100 Jyvaskyla, Finland, EUROPE         */
/* * * Computers Rule 01001111 01001011 * * * * * * * * * * * * * * * * */