Sticky IBM C programming problems (summary of replies)

Alex Matulich alex at bilver.UUCP
Sat Feb 24 13:17:50 AEST 1990


Thanks everybody!
I got inundated with responses to my C programming questions, and here
is the summary, as concise as I could make it.  My original post is quoted
here with the ">" symbol, and my comments to the answers are indicated.

>For the past couple of years I have been writing C programs for IBM
>compatibles using either Microsoft C or Turbo C.  I try to make my software
>look and feel as professional as possible, but during my endeavors I have
>run into some programming problems that I can't figure out, and none of
>the IBM-specific C programming books I have read are any help.  Commercial
>programs do these things, so why can't I?

COMMENT:  Most of the responses I got to my questions were very informative
 and amounted to a polite way of saying "RTFM".  I realized what my problem
 was:  Both the MSC 5.1 and Turbo C 2.0 compilers I use belong to the
 university I work for, and the MSC manuals do NOT answer my questions, which
 is why I asked them; the Turbo C manuals do, however the ones I had
 were from version 1.5 or earlier and I didn't know it!

 I have been using primarily MSC.  Almost every single respondent is a
 Turbo C user, so many of the responses didn't apply to MSC -- I didn't
 realize Turbo C was so popular.  Anybody know anything about Lattice?


>1) Is there a faster way to display character strings than using puts()
>   or printf() without resorting to assembly language?

Use cputs() and cprintf() in the <conio.h> header file.
Use putch(), it's "direct video", might be faster than putc()/putchar()
Use _write().  It is a direct interface to the DOS write call, and does none
of the translations etc. that write() or puts() do.

COMMENT:  I was hoping to preserve portability in my programs by using
 cprintf() everywhere, and, in porting it to a non-IBM computer, using
 #define cprintf printf, but cprintf() doesn't translate the \n character
 properly, nor does it work with ANSI escape codes.  But I do have uses.
 cprintf() in Microsoft C is just as SLOW as printf()!  Turbo C is much
 faster, but the text doesn't inherit the current stdout text colors.
 As far as I can tell, _write() needs a file handle, and I don't know how
 to get a file handle to the video memory.


>2) If I have a text screen set up like I want it, is it possible to save
>   it away somehow so I can display it anytime later by dumping it back
>   into the video memory?  If so, how do I find the address and length 
>   of a video text display?

Curses might do this for you.
Use gettext(), movetext(), puttext() in <conio.h>
For graphics, use _getimage() and _putimage().
On monochrome video cards, (mode 7) the video memory starts at location
0xB000:0000.  In all other text modes, video memory starts at 0xB800:0000.
Use _getvideomode() to determine whether you're mono or color.
 The video memory is arranged in row-major order with two bytes per
 character.  Thus, the address of any character on the screen is
 (base) + (row * 160) + (column * 2).  The first byte is the ASCII code for
 the character, and the second byte is the character's display attribute.

COMMENT:  gettext(), etc. is only available on Turbo C.
 My current project is too big to convert to curses, but I'll look for
 it next time.


>3) How do I display inverse, boldface, or multicolored text without
>   resorting to using ANSI.SYS?

Use textbackground(), textcolor()
Use textattr() with cputs() in <conio.h>
Use escape sequences with puts()
(The programs will be portable to non-completely compatible machines if you
use the escape sequences)

COMMENT:  textbackground() and textcolor() aren't available with MSC.
 Escape sequences don't work with cputs(), cprintf(), etc. but it's not
 a real problem to use escape sequences with stdout functions when speed
 doesn't matter.


>4) The critical error handler gets invoked when the printer needs more
>   paper.  How do I tell if the printer is offline?  The computer hung up
>   last time I tried using fopen() to get a file handle to a printer that
>   was powered off.

Replace the critical error handler (using the setvect() function) with your
 own.  It should check everything you're interested in, and the rest should
 be ignored or passed to the original handler.  Be sure to replace the
 original when you're done!
Use biosprint() in <bios.h>               (Turbo C)
Use _bios_printer(_PRINTER_STATUS, ...);  (MSC)
Some machines have very long timeouts to decide whether or not the printer
 is offline.  You could trap the critical error and check the error code
 yourself with harderr()/hardretn().  If you need to talk directly to a
 printer, use stdprn which should be already opened.
Write to a file and then pass it to the print spooler and you get background
 printing and no worries about programs hanging.

COMMENT:  Hmmm, that's right -- if I wait LONNNG enough, the critical error
 handler does indeed get invoked with a "device not ready" message.  From
 the responses I got, I gather that there's not really any good way to do
 this.  And how do I access "the print spooler"??  Is it a part of MS-DOS?


>5) If a user of my software has a serial printer, how do I set up the
>   serial port parameters (baud rate, xon/xoff, databits, stopbits, etc)?

Use _bios_serialcom()   (MSC)
Use bioscom()           (Turbo C)
Let the user take care of this when he installs the printer.  It is
 not likely to change very often; applications should not need to
 worry about such things.

COMMENT:  If there's a printer on the serial port, it seems virtually
 impossible to tell its status without first knowing what kind of printer
 it is.


>6) I expected to find a function somewhere in the standard library that
>   would read the contents of a disk directory into a string array.  Did
>   I miss it?  I have heard the Lattice compiler has such a function, but
>   I don't have that compiler.  If no such function exists, how is it done?

You use findfirst() and findnext() to step through the directory one matching
entry at a time (this is Turbo C, MSC calls them _dos_findfirst() and
_dos_findnext()).  Also see getcurdir(), getcwd().

COMMENT:  Sure enough, there it is in the MSC manual!  The MSC index listed
 nothing useful under "directory", "directory control", "files", and other
 obvious headings.  _dos_findfirst(), indeed!  I never looked at that one
 long enough to realize what it was.  Also, implementation differences
 between these functions in Turbo C and MSC make for difficult porting.


>7) If my PATH environment variable is set up so that I can run one of my
>   programs from a directory different than the one containing my program,
>   how it possible for my program to determine the directory IT started
>   from?  Or does that information have to be hard-coded in my program?

Look in argv[0], it contains the path of the program.  Then use fnsplit()
 and fnmerge() to manipulate the path.  Works under DOS 3.x.
Use searchpath().
In version 1.x and 2.x, your best bet is to search the current directory,
 and then the path, yourself, which is a pain.

COMMENT:  By golly, it works!  I still don't see it in the MSC manual.  The
only time argv[0] is mentioned is in connection with spawned tasks.


>If you know the answers to at least one of the above questions, or if you
>know the title of a helpful book I can look up, PLEASE e-mail me a reply.

Norton's (Microsoft Press) "Inside the PC"
The manuals that came with Turbo C
For programming the serial port see The Waite Groupe's
       MS-DOS Developer's Guide.
Hunt, "The C Toolbook"
Sam's - Waite Group - Microsoft C for the IBM PC
Ray Duncan's Advanced MSDOS (2nd ed.)
Peter Norton's Programmer's Guide to the IBM PC


Many thanks to all the people who contributed (did I leave anyone out?):

uunet!copper.wr.tek.com!michaelk (Michael D. Kersenbrock)
uunet!bosco.Berkeley.EDU!raymond (Raymond Chen)
RAMontante <uunet!iuvax!bobmon>
Dan Kahn <uunet!rufus.math.nwu.edu!kahn>
uunet!mitisft!dold
uunet!jarthur!dfoster (Derek Foster)
uunet!demott.COM!kdq (Kevin D. Quitt)
uunet!b.gp.cs.cmu.edu!Ralf.Brown
uunet!cis.ohio-state.edu!calvin!richard (Richard Brittain)
uunet!hubcap.clemson.edu!wkay (W. Kevin Kay)
Rajiv Partha Sarathy <uunet!gpu.utcs.utoronto.ca!sarathy>
"Rich Walters" <uunet!math.arizona.edu!arizona!raw>
Russell Herman <uunet!me.utoronto.ca!rwh>
uunet!att!pegasus!psrc (Paul S. R. Chisholm)
uunet!charyb!will (Will Crowder)
Tom Wilson  <uunet!uhccux.uhcc.Hawaii.Edu!wilson>
ucf-cs!cdis-1!tanner
CMH117 at psuvm.psu.edu (Charles Hannum)

-- 
     ///  Alex Matulich
    ///  Unicorn Research Corp, 4621 N Landmark Dr, Orlando, FL 32817
\\\///  alex at bilver.UUCP    ...uunet!tarpit!bilver!alex
 \XX/  From BitNet use: bilver!alex at uunet.uu.net



More information about the Comp.lang.c mailing list