[comp.sys.ibm.pc] using files in C on the IBM PC

pinter@sol.bucknell.edu (pinter) (05/03/89)

I'm having a problem using files in C on the PC, which I never encountered
on the UNIX machines I used in the past.  I have tried two versions of C, both
Turbo and MSC.  Turbo was completely wierd, because whenever I wrote a
character of value 10 (LF) to a file, it would write both a 10 and a 13.
Also, when reading from a file, it would skip over any characters of
value 13.  MSC did not have these problems, but both compilers exhibited
the problem of being completely unable to read past a character of value 26
in a file.  A realize that that is a ctrl-Z or EOF, but it seems there must
be some way to have files which include this character.  Turbo Pascal has no
trouble with it, and I wouldn't want to believe that C is inferior to Pascal
in such a dramatic way.
     Please write me if you have a solution.  Also, please do not use the
news bulletin board since I don't read it very often.  Thanx.

                                  -- Marco Pinter
                                     pinter@sol.bucknell.edu

stephen@ziebmef.uucp (Stephen M. Dunn) (05/12/89)

   Okay, most or all of the common C compilers for DOS operate in
"cooked" mode by default on file accesses.  This means that they treat
^Z (otherwise known as EOF) as the end-of-file marker, and they will
play around with CRs and LFs.  There is another mode of file access
known as "raw" mode to DOS people and "binary" mode to C people.  Instead
of saying R or W as your file access mode, say RB or WB instead and
DOS will stop playing with your file.  You can then read or write whatever
character codes your heart desires without fear of intervention from
DOS.
-- 
-------------------------------------------------------------------------------
! Stephen M. Dunn              stephen@ziebmef.UUCP ! DISCLAIMER:  Who'd ever !
! Take off to the Great White North eh, ya hosehead ! claim such dumb ideas?  !
-------------------------------------------------------------------------------

jeffery@jsheese.FIDONET.ORG (Jeff Sheese) (05/13/89)

References: <1989May11.203209.9152@ziebmef.uucp>

In an article of <12 May 89 00:32:07 GMT>, stephen@ziebmef.uucp (Stephen M.  
Dunn) writes:

 >   Okay, most or all of the common C compilers for DOS operate in
 >"cooked" mode by default on file accesses.  This means that they treat
 >^Z (otherwise known as EOF) as the end-of-file marker, and they will
 >play around with CRs and LFs.  There is another mode of file access
 >known as "raw" mode to DOS people and "binary" mode to C people.  Instead
 >of saying R or W as your file access mode, say RB or WB instead and
 >DOS will stop playing with your file.  You can then read or write 
 >whatever character codes your heart desires without fear of intervention 
 >from DOS.

Turbo C has a feof() function to determine the logical end of file, regardless  
of the ^Z.  Using ^Z as an EOF mark is a layover from CP/M days for  
compatibility reasons.
 
--  
Jeff Sheese - via FidoNet node 1:109/116
UUCP: ...!netsys!jsheese!jeffery
ARPA: jeffery@jsheese.FIDONET.ORG
(I am sole owner.  My opinions represent my company.)
(Send all flames to null@jsheese.Fidonet.ORG)

toma@tekgvs.LABS.TEK.COM (Tom Almy) (05/15/89)

In article <1989May11.203209.9152@ziebmef.uucp> stephen@ziebmef.UUCP (Stephen M. Dunn) writes:
>
>   Okay, most or all of the common C compilers for DOS operate in
>"cooked" mode by default on file accesses.  This means that they treat
>^Z (otherwise known as EOF) as the end-of-file marker, and they will
>play around with CRs and LFs.  There is another mode of file access
>known as "raw" mode to DOS people and "binary" mode to C people.  Instead
>of saying R or W as your file access mode, say RB or WB instead and
>DOS will stop playing with your file.  You can then read or write whatever
>character codes your heart desires without fear of intervention from
>DOS.

Actually there are two different features (?) being discussed here --
"raw" vs "cooked" and "ascii" vs "binary".  

"ascii" vs "binary" is an artifact of C's treatment of end of lines.  DOS
denotes end of lines with a CR LF pair, while C uses a single LF character.
When a file is opend "ascii" (usually the default, but can be forced by
opening "ra" or "wa" in most C libraries) CR's are stripped on input and
prepended to any LF's on output.  

"raw" vs "cooked" is a DOS driver feature (also in UNIX).  If, for instance,
the keyboard is "raw" control-C characters will always be passed to the
program rather than treated as special case interrupt character.  Also
display output speed is improved in RAW mode because the keyboard buffer
does not need to be checked, and certain drivers (such as NANSI.SYS or
FANSI-CONSOLE) can work more efficiently.  If you are doing graphics to a
printer, you need to set raw mode.  

I'm not sure if the various C library setmode() routines affect just 
"ascii" vs "binary" or also change "raw" vs "cooked".  I always issue
the DOS calls directly to set raw mode.

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

davis@rm1.UUCP (Gary A. Davis) (06/22/89)

This is in response to an article about ascii/binary and raw/cooked
I/O from Tom Almy. 

At then end, Tom
mentioned that he always issued the DOS calls directly to set raw
mode (for the printer). What commands are these? I am sort of new to
the IBM PC world. I have a graphics file to print generated by a
filter and it happens to contain bit codes that happen to look like
CR/LFs and ^Zs. I can print the file ok by COPY/B FILE PRN (I think
this is the command I used). It fails due to a ^Z byte using the PRINT
FILE command. I would like to use the spooler via the PRINT but is
there a binary option? The filter creates the file but I think there
are problems redirecting it to the printer. The filter does open the
output (stdout) as binary (via setmode()) and is getting created ok
when it is a disk file, but not when redirected as in:

	filter < input.fil > PRN

Any ideas on this? Thanks...

Gary
-- 
  Gary A. Davis
  Racal-Milgo, P.O. Box 407044, Fort Lauderdale, Fl 33340, (305) 476-4393

  {{mailrus,gatech}!uflorida,ucf-cs}!novavax!rm1!davis

marc@rna.UUCP (Marc Johnson) (07/04/89)

In article <114@rm1.UUCP> davis@rm1.UUCP (Gary A. Davis) writes:
>
>This is in response to an article about ascii/binary and raw/cooked
>I/O from Tom Almy. 
>
>At then end, Tom
>mentioned that he always issued the DOS calls directly to set raw
>mode (for the printer). What commands are these? I am sort of new to
>the IBM PC world. I have a graphics file to print generated by a
>filter and it happens to contain bit codes that happen to look like
>CR/LFs and ^Zs. I can print the file ok by COPY/B FILE PRN (I think
>this is the command I used). It fails due to a ^Z byte using the PRINT
>FILE command. I would like to use the spooler via the PRINT but is
>there a binary option? The filter creates the file but I think there
>are problems redirecting it to the printer. The filter does open the
>output (stdout) as binary (via setmode()) and is getting created ok
>when it is a disk file, but not when redirected as in:
>
>	filter < input.fil > PRN
>
>Any ideas on this? Thanks...
>
>Gary
>-- 
>  Gary A. Davis
>  Racal-Milgo, P.O. Box 407044, Fort Lauderdale, Fl 33340, (305) 476-4393
>
>  {{mailrus,gatech}!uflorida,ucf-cs}!novavax!rm1!davis

I don't have any ideas on how to get around the ^Z problem, but I can help
you with the DOS calls aprt of your question.  DOS provides some low-level
system calls to perform basic system tasks.  You can access these by
using interrupt 21 (INT 21).  You'll need some kind of DOS reference to
learn what all the DOS calls are (Microsoft Press publishes an excellent
DOS Programmer's Reference, and IBM of course has a manual on this, though
I forget just which one it is).  I do believe there is a call to twiddle
the printer to the proper mode for raw I/O, but you'll need the reference
work to do it.  You'll need to include a header file (Microsoft C calls
it "dos.h", I think Lattice calls it "dosregs.h") which defines a struct
for the registers.  You have to load the registers with the proper values
for the DOS call, including the ID of the call you want, then call C's
intdos() or int86() or equivalent in your C to get the INT 21.  It's not
tough once you've seen it done once or twice.  Here's an example, in Microsoft
C 4.0 to get the current date and time from INT 21 and convert them to
DOS directory format:

/*
 * dir_date - Get current date and time from DOS and convert to directory form
 */
#include <dos.h>

dir_date(date, time)
unsigned *date, *time;
{
	union REGS iregs, oregs;

	/* get current date */
	iregs.h.ah = 0x2A;	/* DOS call 2A in high-byte of register A */
	intdos(&iregs, &oregs);	/* do INT 21 */
	/*
	 * The union oregs contains the results:
	 * register C (word) contains year,
	 * high-byte of register D has month,
	 * low-byte of register D has day
	 */
	*date = ((oregs.x.cx - 1980) << 9) | (oregs.h.dh << 5) | oregs.h.dl;
	
	/* get current time */
	iregs.h.ah = 0x2C;	/* DOS call 2C in high-byte of register A */
	intdos(&iregs, &oregs);	/* do INT 21 */
	/*
	 * The union oregs contains the results in registers C and D
	 */
	*time = (oregs.h.ch << 11) | (oregs.h.cl) << 5) |
		((oregs.h.dh >> 1) & 0x1f);
}

For calls that could have errors you should check the error as indicated in
the DOS call description (usually, the carry is set, and you need to check
one of the registers).

Good luck.
marc
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
= Marc Johnson			    BITNET:   rna!marc@rockvax.bitnet         =
= Rockefeller Univ. Neurobiology    UUCP:     ...cmcl2!rna!marc               =
= New York City                     INTERNET: marc%rna@rocky2.rockefeller.edu =
=                                             (129.85.2.1)                    =
=                                                                             =
= "Gimme the beat boys and free my soul, I wanna get lost in your rock & roll =
=                           ...and drift away"                                =
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=