Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Avoiding new line reading a string with readline

91 views
Skip to first unread message

Carlo Zanziba

unread,
Oct 28, 2011, 2:58:36 AM10/28/11
to
Hi,

I'd want to achieve the following effect during an input from terminal
using readline in a C program:

the user types something (the input line), and the input routine does
not go to a new line, rather types something in response and only after
this response the new line is executed.

An example is the gforth output (the intended effect I want to achieve):

1 2 + . [ENTER] 3 ok
_

The user presses [ENTER] after last character (the dot), the system
prints the answer (3), the ok label and only THEN goes to the new line.

What I get using simply readline is of course:

1 2 + .
2 ok _

or similar.

Any ideas?

Thanks in advance.

-- Carlo
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

fasked

unread,
Oct 28, 2011, 3:18:57 PM10/28/11
to
> Any ideas?
As far as I know that's impossible to achieve using C standard library
only. I think you will have to use ncurses-like libraries.

Thomas Richter

unread,
Oct 28, 2011, 3:19:28 PM10/28/11
to
On 28.10.2011 08:58, Carlo Zanziba wrote:

> the user types something (the input line), and the input routine does
> not go to a new line, rather types something in response and only after
> this response the new line is executed.

> Any ideas?

Standard ANSI C does not provide a solution for this problem. However,
you might want to look into the "curses" library which is available on
many systems.

Greetings,
Thomas

Dag-Erling Smørgrav

unread,
Oct 28, 2011, 3:20:28 PM10/28/11
to
Carlo Zanziba <zanzib...@NOSPAMlibero.it> writes:
> the user types something (the input line), and the input routine does
> not go to a new line, rather types something in response and only
> after this response the new line is executed.

This is not possible in pure C, but your implementation almost certainly
has a library that provides this functionality. You should ask in a
newsgroup or other forum dedicated to your operating system and C
implementation.

DES
--
Dag-Erling Smørgrav - d...@des.no

Gordon Burditt

unread,
Oct 28, 2011, 3:20:59 PM10/28/11
to
> I'd want to achieve the following effect during an input from terminal
> using readline in a C program:
>
> the user types something (the input line), and the input routine does
> not go to a new line, rather types something in response and only after
> this response the new line is executed.
>
> An example is the gforth output (the intended effect I want to achieve):
>
> 1 2 + . [ENTER] 3 ok
> _
>
> The user presses [ENTER] after last character (the dot), the system
> prints the answer (3), the ok label and only THEN goes to the new line.

There is no way to achieve this using standard C. One way to do
it on UNIX is to turn off character echo and echo the characters
after you read them (and only when you want to; don't echo the ENTER
which in your example messes up the line). However, you don't want
the user "typing blind" so they can't see if they type the wrong
character. Also, handling typing mistakes with such characters as
"backspace" is now up to you.

There is also no way in standard C to read characters one at a
time. Under UNIX, there are "cbreak" mode and "raw" mode.

The simplest way to invoke these is probably:
system("stty -echo cbreak");
It is left as an exercise for the reader to figure out how to
undo this before terminating the program.

Even within UNIX, there are several different methods of
using ioctl() to accomplish the same thing, which is faster
and does not require another process, but they are mutually
incompatible. Having a #ifinclude would be useful here.


If you wanted this to work on Windows, it might have a similar
function.

Richard Damon

unread,
Oct 28, 2011, 3:21:14 PM10/28/11
to
On 10/28/11 2:58 AM, Carlo Zanziba wrote:
> Hi,
>
> I'd want to achieve the following effect during an input from terminal
> using readline in a C program:
>
> the user types something (the input line), and the input routine does
> not go to a new line, rather types something in response and only after
> this response the new line is executed.
>
> An example is the gforth output (the intended effect I want to achieve):
>
> 1 2 + . [ENTER] 3 ok
> _
>
> The user presses [ENTER] after last character (the dot), the system
> prints the answer (3), the ok label and only THEN goes to the new line.
>
> What I get using simply readline is of course:
>
> 1 2 + .
> 2 ok _
>
> or similar.
>
> Any ideas?
>
> Thanks in advance.
>
> -- Carlo

There is no way to do this in standard C, as it doesn't define anywhere
near that level of detail on control over a console (since you don't
need to have a console in standard C).

Even thinking about what you want to do, since you want some characters
(the enter) to not be echoed immediately on input, you need to switch
the console to not echo characters at all (I don't know of any systems
where you can tell the console to just not echo enter), and then have
your program read one character at a time, echo it if not an enter, and
build up the input buffer. Note that because you have taken over that
much control, you are also going to have to process all editing
operations like backspace.

The way to access the console in this sort of mode is system specific,
so you will need to read your system documentation (it may be in the
compiler, it may be in the OS, or a bit of both), to figure out how to
do this.

Alan Curry

unread,
Nov 2, 2011, 1:48:58 PM11/2/11
to
In article <clcm-2011...@plethora.net>,
Carlo Zanziba <zanzib...@NOSPAMlibero.it> wrote:
>Hi,
>
>I'd want to achieve the following effect during an input from terminal
>using readline in a C program:
>
>the user types something (the input line), and the input routine does
>not go to a new line, rather types something in response and only after
>this response the new line is executed.
>
>An example is the gforth output (the intended effect I want to achieve):
>
>1 2 + . [ENTER] 3 ok

gforth is manipulating the tty modes to achieve this effect. If you want
to see exactly how, gforth's source is available. It contains a lot of
#ifdefs to use various ancient unix ioctls as well as the modern
tcsetattr. In a new program you shouldn't mess with the ancient ioctls.
Just use tcsetattr. It was standardized a long time ago.

But I think you should reconsider the whole thing. gforth is the only
unix program I've ever seen with this interface. It's weird. It's a poor
fit for the environment it runs in. This idea of suppressing the newline
echo so you can print a response to the right of a line of input instead
of where it would normally go... it's just too clever and unexpected.

--
Alan Curry

Francis Glassborow

unread,
Nov 2, 2011, 1:49:57 PM11/2/11
to
And that is a long way from being a trivial bit of coding (I know
because I did it in another language). In addition as other posters have
mentioned, the result will be non-portable. I really wonder if there is
there enough benefit to make the effort worth while. It may seem that as
long as you know that you will only run your code on a specific platform
that it is worth going ahead, but unless you write all the code yourself
(i.e. do not depend on a third party library) all will be fine. But I
bet that the result will be wanted on an upgrade and it will not work
and will need a complete rewrite.

Now consider a different approach to that suggested above and by other
posters. Use the standard input routines but tweak the output by using
something such as the ncurses library to redisplay the input without the
newline but with the output appended finally ended with cr/nl (i.e. a
'\n' character.

Marc Espie

unread,
Mar 19, 2012, 2:40:32 PM3/19/12
to
In article <clcm-2011...@plethora.net>,
Gordon Burditt <gordon...@burditt.org> wrote:
>There is also no way in standard C to read characters one at a
>time. Under UNIX, there are "cbreak" mode and "raw" mode.
>
>The simplest way to invoke these is probably:
> system("stty -echo cbreak");
>It is left as an exercise for the reader to figure out how to
>undo this before terminating the program.
>
>Even within UNIX, there are several different methods of
>using ioctl() to accomplish the same thing, which is faster
>and does not require another process, but they are mutually
>incompatible. Having a #ifinclude would be useful here.

In Unix land, this got standardized about 10 to 20 years ago.
Using ioctl to uncook your terminal is a bad idea, use termios (which
is basically a portable wrapper around the required ioctls)

Works on anything which is still relevant...
0 new messages