[comp.lang.c] Echoing chars and input functions

dsill@NSWC-OAS.ARPA (Dave Sill) (08/16/88)

reg%lti.UUCP@bu-it.BU.EDU (Rick Genter x18) writes:
>Scott Wilson quotes the "Lightspeed 3.0 Standard Libraries Reference:
>
>>      getchar() gets the next character from stdin.  The character
>>      is not echoed to stdout.
>
>and asks if this is fixed in ANSI C.  I haven't seen the most recent
>incarnation of the dpANS, but I certainly hope it doesn't address 
>echoing.  That is an operating system function; it has nothing to do
>with the buffered I/O library.

I agree with Lightspeed that characters gotten from standard input
from getchar should not be echoed to standard output.  It would be
incredibly stupid to echo my keystrokes to file or pipe.  Of course,
the correct thing to do is echo the characters to the screen, but only
if they were entered interactively.
 
I have a problem saying this is in the domain of the operating system,
though.  What good is it to have standardized I/O functions if they
aren't guaranteed to work similarly on all systems?  What, then, is
the portable way to input a character from standard input, echoing the
character to the screen when necessary?
 

gwyn@smoke.ARPA (Doug Gwyn ) (08/18/88)

In article <8808160751.aa03016@SMOKE.BRL.MIL> dsill@NSWC-OAS.ARPA (Dave Sill) writes:
>What, then, is the portable way to input a character from standard input,
>echoing the character to the screen when necessary?

We already answered that!  It's
	c = getchar();

swarbric@tramp.Colorado.EDU (Frank Swarbrick) (08/18/88)

In article <8349@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>In article <8808160751.aa03016@SMOKE.BRL.MIL> dsill@NSWC-OAS.ARPA (Dave Sill) writes:
>>What, then, is the portable way to input a character from standard input,
>>echoing the character to the screen when necessary?
>
>We already answered that!  It's
>	c = getchar();

I could have sworn someone said their compiler did not echo the character when
they used this.  Did I misunderstand someone, or is their compiler just
non-conformant (broken)?

Frank Swarbrick (and, yes, the net.cat)           swarbric@tramp.Colorado.EDU
...!{ncar|nbires}!boulder!tramp!swarbric
"Quick to judge, quick to anger -- slow to understand;
 Ignorance and prejudice -- and fear walk hand in hand."  --Rush

williamo@hpcupt1.HP.COM (William O'Saughnessy) (08/18/88)

OK, what is the proper and portable way to get a character from stdin
without having it echoed to the screen?!!!!

Basic may have C beat here it defines the way with INKEY but there 
appears to be no machine independent way of doing it in C!

karl@haddock.ima.isc.com (Karl Heuer) (08/18/88)

In article <2821@boulder.Colorado.EDU> swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>In article <8349@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>[The correct way to input a character, with echo when necessary, is]
>>	c = getchar();
>
>I could have sworn someone said their compiler did not echo the character when
>they used this.  Did I misunderstand someone, or is their compiler just
>non-conformant (broken)?

Since the compiler in question did echo when using fgets, it is indeed broken
according to the dpANS (which specifies that all I/O functions behave as if
they use getc/putc as primitives).

Now, it would be valid and conforming for the implementation to *never* echo.
There's nothing wrong with this; Unix programs generally do this if you've put
the terminal in noecho mode before starting the program.  But if this would
make C programs behave in a manner which is non-intuitive for the system in
question, then it's a poor quality implementation.  It's obvious that stdio
should use, as it's lowest-level primitive, whatever is the natural I/O
mechanism of the host.

No, the dpANS doesn't *force* this.  But, to paraphrase the Rationale, "It's
possible to create an implementation which conforms to the letter of the
Standard and yet is useless."

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

gwyn@smoke.ARPA (Doug Gwyn ) (08/19/88)

In article <2821@boulder.Colorado.EDU> swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>In article <8349@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>In article <8808160751.aa03016@SMOKE.BRL.MIL> dsill@NSWC-OAS.ARPA (Dave Sill) writes:
>>>What, then, is the portable way to input a character from standard input,
>>>echoing the character to the screen when necessary?
>>We already answered that!  It's
>>	c = getchar();
>I could have sworn someone said their compiler did not echo the character when
>they used this.

How could the COMPILER do diddly about a character received at run time?
It's not even running at that point.

The point is, at the abstract machine level, which is the target for C
application source code, getchar() simply returns the next character from
standard input.  No other portable method (other than fully equivalent
getc(), scanf(), and fscanf() invocations) is available for this.
WHATEVER extra stuff is associated with getting an input character (e.g.
echoing) is dealt with somewhere else, not by the C application code.  For
example, the C library may have to determine where characters are coming
from and possibly echo them as they are typed, also providing a cursor and
input line editing and any other user-oriented features that are not
already provided at a lower level than the C library.  Most operating
systems will do this before the characters reach the C library, but some
may be deficient so that the C library has to take care of such details.
In any case, getchar() is all that is necessary at the C application
programming level.

Notice that many interactive applications need for input characters to NOT
be echoed.  Usually this is arranged by first asking the operating system
(or a part of the C library, if it's performing terminal handler functions)
to turn off input echoing.  On UNIX this is done via a certain ioctl()
system call; on other systems a different method may be necessary.

jfh@rpp386.UUCP (The Beach Bum) (08/19/88)

In article <2821@boulder.Colorado.EDU> swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>In article <8349@smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes:
>>In article <8808160751.aa03016@SMOKE.BRL.MIL> dsill@NSWC-OAS.ARPA (Dave Sill) writes:
>>>What, then, is the portable way to input a character from standard input,
>>>echoing the character to the screen when necessary?
>>
>>We already answered that!  It's
>>	c = getchar();
>
>I could have sworn someone said their compiler did not echo the character when
>they used this.  Did I misunderstand someone, or is their compiler just
>non-conformant (broken)?

perhaps what needs to be said is that getchar() does not echo characters.
the operating system does.  if ms-dos does not perform character echoing
when reading from the keyboard, then this becomes an operating system
issue, not a language one.  likewise for all operating systems which C
is used on.  the description for getchar() is "read a character from
standard input".

a portable way to do "echoing" would be

	(c = getchar ()) != EOF && putchar (c);

this explicitly echoes the characters.  it is also "broken" on unix.
-- 
John F. Haugh II                 +--------- Cute Chocolate Quote ---------
HASA, "S" Division               | "USENET should not be confused with
UUCP:   killer!rpp386!jfh        |  something that matters, like CHOCOLATE"
DOMAIN: jfh@rpp386.uucp          |         -- apologizes to Dennis O'Connor

burgett@steel.COM (Michael Burgett) (08/19/88)

In article <2821@boulder.Colorado.EDU> swarbric@tramp.Colorado.EDU (Frank Swarbrick) writes:
>>>What, then, is the portable way to input a character from standard input,
>>>echoing the character to the screen when necessary?
>>
>>We already answered that!  It's
>>	c = getchar();
>
>I could have sworn someone said their compiler did not echo the character when
>they used this.  Did I misunderstand someone, or is their compiler just
>non-conformant (broken)?

I think the point is that terminal echo is controlled by the operating system
and NOT by the c library function used to get the character.

		mike burgett

					burgett!adobe.decwrl.dec.com

chris@mimsy.UUCP (Chris Torek) (08/19/88)

In article <5940003@hpcupt1.HP.COM> williamo@hpcupt1.HP.COM (William
O'Saughnessy) writes:
>OK, what is the proper and portable way to get a character from stdin
>without having it echoed to the screen?!!!!

There is no such way.  C may legitimately be used on a half-duplex
terminal.  (For that matter, there may be no `screen'.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris

burgett@steel.COM (Michael Burgett) (08/19/88)

In article <5940003@hpcupt1.HP.COM> williamo@hpcupt1.HP.COM (William O'Saughnessy) writes:
>
>OK, what is the proper and portable way to get a character from stdin
>without having it echoed to the screen?!!!!
>
>Basic may have C beat here it defines the way with INKEY but there 
>appears to be no machine independent way of doing it in C!

Sigh... if you are on unix, check the ioctl system library functions to see
how to toggle terminal echo, if your're on some other OS RTFB for that OS, 
C treats io as a file... do you *really* think C would echo characters read 
from a file back to it?  One has to remember that C was designed to be 
portable... a claim that I've never (seriously) heard mentioned about that
other language (and I do use that term loosely...) you mentioned.

	mike burget

			burgett!adobe@decwrl.dec.com

andru@rhialto.SGI.COM (Andrew Myers) (08/19/88)

In article <5940003@hpcupt1.HP.COM>, williamo@hpcupt1.HP.COM (William O'Saughnessy) writes:
> 
> OK, what is the proper and portable way to get a character from stdin
> without having it echoed to the screen?!!!!
> 
> Basic may have C beat here it defines the way with INKEY but there 
> appears to be no machine independent way of doing it in C!

Mentioning "INKEY" and machine independence in the same sentence is a
bit ridiculous. Systems in which the ability to control character echo
are typically interpreted, and the language effectively is the operating
system. As indicated by another poster, the task of controlling character
echo is usually handled through the operating system. Many BASICs don't
even provide this capability (e.g. Applesoft, as I recall. [Yes, you could
do it through PEEK, but that's hardly the same]).

Andrew

karl@haddock.ima.isc.com (Karl Heuer) (08/19/88)

In article <5940003@hpcupt1.HP.COM>  williamo@hpcupt1.HP.COM (William O'Saughnessy) writes:
>OK, what is the proper and portable way to get a character from stdin
>without having it echoed to the screen?!!!!

I generally use tioset(), which is portable to as many implementations as I've
bothered to implement it on.

>Basic may have C beat here it defines the way with INKEY

Do you really believe that INKEY is portable?  How many flavors of BASIC have
you used?

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

swilson%thetone@Sun.COM (Scott Wilson) (08/20/88)

>Most operating
>systems will do this before the characters reach the C library, but some
>may be deficient so that the C library has to take care of such details.

For clarification, my original post on this subject was in reference
to getchar() as implemented in THINK's LightspeedC 3.0 for the Macintosh.
getchar() in this environment does not echo what is read interactively
(interestingly, LSC has a Set_Echo function that can turn echo on and
off but I don't think getchar() is one of the functions effected by it).
The Macintosh environment is quite different from more traditional
environments like DOS or UNIX and there really is no notion of a "terminal".
I think it is unfair to characterize OS's that don't echo as being
"deficient".  LSC, in an attempt to provide to provide compatibility,
takes on the responsibility of creating a terminal-like window so stdio
functions will work as expected.  I don't think it is reasonable to say
that the C environment need not be concerned about things such as echoing
because it is an OS problem when the host OS has no concept of a terminal.

What I would like to see from ANSI C is something like:  in the abscence
of a language-independent method of altering interactive i/o behavior
(such as provided by stty under UNIX), the standard library implementation
should provide calls to alter behavior such as input echoing, buffering,
and editing.  I realize that this would be difficult or impossible to
enforce because of the connection to the OS.

All that I really want is some portable way to read interactive input
that looks roughly the same across implmentations of C.  As long as
most implementations echo input fetched with getchar() and LSC doesn't
(and the OS can't) then this isn't possible.  My complaint is that ANSI
doesn't do anything to solve the problem.  Ultimately the best way to
solve this may be to bitch to THINK about their poor "UNIX compatibility"
with respect to getchar().

BTW, I do realize that LSC does allow input that is echoed by way of the
gethce() function, but that isn't exactly portable.


--
Scott Wilson		arpa: swilson@sun.com
Sun Microsystems	uucp: ...!sun!swilson
Mt. View, CA

karish@denali.stanford.edu (Chuck Karish) (08/20/88)

In article <64974@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes:
[ Lightspeed C on the Macintosh doesn't echo what's read by getchar() ]

>BTW, I do realize that LSC does allow input that is echoed by way of the
>gethce() function, but that isn't exactly portable.

OK, so stick a call to getce() into a Mac-dependent fubction or macro,
and call that function whenever you want this echoing behavior.
Whenever you port to another environment, write another
environment-specific interface routine.  The main body of your code
will then be portable.

Chuck Karish	ARPA:	karish@denali.stanford.edu
		BITNET:	karish%denali@forsythe.stanford.edu
		UUCP:	{decvax,hplabs!hpda}!mindcrf!karish
		USPS:	1825 California St. #5   Mountain View, CA 94041

gwyn@smoke.ARPA (Doug Gwyn ) (08/21/88)

In article <64974@sun.uucp> swilson@sun.UUCP (Scott Wilson) writes:
-I think it is unfair to characterize OS's that don't echo as being
-"deficient".  LSC, in an attempt to provide to provide compatibility,
-takes on the responsibility of creating a terminal-like window so stdio
-functions will work as expected.

If they really expect you to type "blind" in their emulated terminal
window, I would surely call that deficient!

In a scenario like this, part of the "OS" is being provided by
the C run-time environment implementation.

-I don't think it is reasonable to say
-that the C environment need not be concerned about things such as echoing
-because it is an OS problem when the host OS has no concept of a terminal.

That's not what I said.  I said it is not a problem to be addressed
by the application code.  LSC definitely should provide reasonable
support for terminal-like input, including echoing and input line
editing, in SOME part of their environment.  It should not require
special action by the typical application to get this.

-All that I really want is some portable way to read interactive input
-that looks roughly the same across implmentations of C.  As long as
-most implementations echo input fetched with getchar() and LSC doesn't
-(and the OS can't) then this isn't possible.  My complaint is that ANSI
-doesn't do anything to solve the problem.

"ANSI" is in no position to solve a design problem in the implementation
of a particular product.  You should nag the vendor to do a better job.

danw@tekchips.CRL.TEK.COM (Daniel E. Wilson;1432;58-790;;) (08/22/88)

In article <4164@adobe.COM>, burgett@steel.COM (Michael Burgett) writes:
> In article <5940003@hpcupt1.HP.COM> williamo@hpcupt1.HP.COM (William O'Saughnessy) writes:
> >Basic may have C beat here it defines the way with INKEY but there 
> >appears to be no machine independent way of doing it in C!
> 
> a claim that I've never (seriously) heard mentioned about that
> other language (and I do use that term loosely...) you mentioned.
> 

I agree. BASIC is about as worthless of a language I can think of.
-------------------
Dan Wilson	<shadow.tekfdi.COM>

peter@ficc.UUCP (Peter da Silva) (08/23/88)

What lightspeed 'C' should have done is:

	(1) Make getchar() echo by default, using the same routines
	    that fread() and gets() use, and...

	(2) Provide an emulation of ioctl() or sgtty().

Manx does this, at least on the Amiga.

Even better would have been to provide a pseudo-device that was a terminal
window, like most windowing systems support (xterm, CON:, whatever Apollo
uses, MS/DOS windows in Windows, ...).
-- 
Peter da Silva  `-_-'  Ferranti International Controls Corporation.
"Have you hugged  U  your wolf today?"     sugar.uu.net!ficc!peter.

dmg@ssc-vax.UUCP (David Geary) (08/24/88)

In article <5940003@hpcupt1.HP.COM>, williamo@hpcupt1.HP.COM (William O'Saughnessy) writes:
> 
> OK, what is the proper and portable way to get a character from stdin
> without having it echoed to the screen?!!!!
> 
> Basic may have C beat here it defines the way with INKEY but there 
> appears to be no machine independent way of doing it in C!

  Yeah, but there appears to be no machine independent way of doing
  BASIC(K)...
-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~ David Geary, Boeing Aerospace,               ~ 
~ Seattle - "THE DRIZZLE CAPITAL OF THE WORLD" ~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

jfh@rpp386.UUCP (The Beach Bum) (08/24/88)

In article <1342@ficc.UUCP> peter@ficc.UUCP (Peter da Silva) writes:
>What lightspeed 'C' should have done is:
>
>	(1) Make getchar() echo by default, using the same routines
>	    that fread() and gets() use, and...
>
>	(2) Provide an emulation of ioctl() or sgtty().

this is the best way to handle messy-dos that i've seen yet.  if
it could be limited to the console it might even work ;-).

it still does not address the issue of i/o redirection from a file
or a pipe, or freopen calls or anything.  in the presence of a suitable
emulation for isatty(), filbuf() [ or whatever routine the macro calls ]
could test for the console being the input device.

problems abound.  the issue of line buffering and editing aren't even
addressed.  adding the entire unix line discipline to the c runtime
is not a pretty thought.
-- 
John F. Haugh II (jfh@rpp386.UUCP)                           HASA, "S" Division

    "If the code and the comments disagree, then both are probably wrong."
                -- Norm Schryer

peter@ficc.uu.net (Peter da Silva) (08/25/88)

In article <5758@rpp386.UUCP>, jfh@rpp386.UUCP (The Beach Bum) writes:
> In article <1342@ficc.UUCP> peter@ficc.UUCP (Peter da Silva) writes:
> >	(2) Provide an emulation of ioctl() or sgtty().

> this is the best way to handle messy-dos that i've seen yet.  if
> it could be limited to the console it might even work ;-).

I believe Manx for MS-DOS does this, by having it use different system
calls depending on what the value of the ECHO flag is. It doesn't have
a complete emulation of struct termio, just a few flags.

I'd hate to try to get ksh running under Lightspeed. I hate to think
of what struct _iob looks like :->.
-- 
Peter da Silva  `-_-'  Ferranti International Controls Corporation.
"Have you hugged  U  your wolf today?"     sugar.uu.net!ficc!peter.