Solved

console input

Posted on 2000-02-15
15
269 Views
Last Modified: 2010-04-22
Gday,

Say I have a console app that has a menu like this say:

1. go here
2. go there
q. quit

At the moment I am using read() calls to read in the data.. the problem is the read call waits for the enter button to be pressed before stopping reading. This sux.. I want a way so that if 1 is pressed *instantly* my program reacts to the input and goes to 1.. I don't want to wait for say 1 and then "enter".

Anyone got any ideas?
0
Comment
Question by:ramsay
  • 5
  • 5
  • 4
  • +1
15 Comments
 
LVL 40

Expert Comment

by:jlevie
ID: 2525689
It waits because you are doing buffered reads. You at least need to use unbuffered asynchronus I/O and quite possibly need to associate a signal to tell when a character has been typed. The man page on open and fcntl would be good to look at.
0
 
LVL 1

Author Comment

by:ramsay
ID: 2529769
i want an example
0
 
LVL 1

Author Comment

by:ramsay
ID: 2533819
Adjusted points to 200
0
 
LVL 3

Accepted Solution

by:
alien_life_form earned 200 total points
ID: 2534234
You need to do raw input and your best bet for doing it portably would be using ncurses, with something like:

#include <curses.h>

initscr();
cbreak();
noecho();
/*
 * your stuff here
 */

endwin();

If you want to do it the hard way, do a  man termios and prepare to meet madness on your path.

Alternatively, and for a quicky, this might work:
system("stty cbreak </dev/tty >/dev/tty 2>&1");
c=getc(stdin);
system("stty -cbreak </dev/tty >/dev/tty 2>&1");

but it's pretty ugly.

Also, you'll have to unbuffer stdin before it'll work.

Cheers,
     alf

0
 
LVL 1

Author Comment

by:ramsay
ID: 2544904
thanks alf.. i'll look into it now
0
 
LVL 4

Expert Comment

by:nils pipenbrinck
ID: 2557139
what about that?

#include <stdio.h>

int menu (int argc, char **args)
{
  char c;
  printf ("a. foo\n");
  printf ("b. bar\n");
  printf ("c. quit\n");

  c = getch();
  switch (c)
  {
    case 'a':
      // code for a goes here
    break;
    case 'b':
      // code for b goes here
    break;
    case 'q':
      return;
    break;
  }
}

getch just returns the first character
from stdin. if there is no such charater it waits for one..

  Nils

0
 
LVL 4

Expert Comment

by:nils pipenbrinck
ID: 2557142
ehm. ****

getch needs conio.h..

forgot to include it.

Nils
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 3

Expert Comment

by:alien_life_form
ID: 2557224
Grretings.

Nils, may work *under windows* (which also has conio.h). But, this is a Linux forum - wrong OS.

Cheers,
 alf
0
 
LVL 4

Expert Comment

by:nils pipenbrinck
ID: 2557394
Hm...

Ok, I'm from the win32 corner, that's true..

But isn't conio.h part of the ANSI clib standard?

at least fgetc is ANSI (according to my clib reference)..

so char c = fgetc (stdin) should work on any os supporting a ANSI clib.

Nils

0
 
LVL 3

Expert Comment

by:alien_life_form
ID: 2557749
Greetings.

i) No, conio.h is a windows-only header.

ii) Yes, fgetc and company are ANSI, however, the problem with console input is the line discipline: the character is made available only after the user has pressed enter (line buffering, and then some). This behavior is what the original poster wants to avoid.

Cheers,
   alf
   
0
 
LVL 4

Expert Comment

by:nils pipenbrinck
ID: 2557979
hm..

as you know I'm no linux expert, but stdio.h is ansi standard, isn't?

maybe a setbuf (stdin, 0) will do the job.. that would disable all buffering.

Nils
0
 
LVL 3

Expert Comment

by:alien_life_form
ID: 2558096
Greetings.

That would indeed  be correct for a file. However, here we're talking a file descriptor that's really connected to a terminal. When this is the case,
you're really talking to a device driver responsible for shuttling keystrokes back and forth from the keyboard to the stdio data structures.

This driver interfaces to stdio through (?) a system layer that can be controlled by means provided by termios.h and/or ioctl.h.

Problem is, this interface is not, will I put it mildly, the most user friendly piece of the Unix programming environment (the un-mild version is that it's mummbo-jumbo). The historical reason is that it allows you to handle many different terminal-like devices, including teletypes and long-forgotten terminal brands.

However. What this subsystem does, roughly, is slapping a layer of preprocessing between the device itself and stdio. This is often referred to as 'cooked' mode, and part of it is the line discipline bit: stdio will not get hold of the keystrokes until they have been processed *and* <enter> has been pressed. So just unbuffering stdin won't be sufficient (unlike what happens when you read from, say, a pipe, where unbuffering is enough).

If you want to get rid of this, you have to put the terminal in 'raw' or 'cbreak' mode, and be prepared to handle keystrokes.

Hence this thread.

Cheers,

   alf

0
 
LVL 4

Expert Comment

by:nils pipenbrinck
ID: 2558218
strange system you are working on.for gods sake I have my win32 :)

I'll uncheck the notify.. it looks like I can't help here at all..

bye,
  Nils


0
 
LVL 3

Expert Comment

by:alien_life_form
ID: 2576089

Ramsay, is the problem closed? If so,
pls. take appropriate action.

Cheers,
   alf

0
 
LVL 1

Author Comment

by:ramsay
ID: 2579439
Thanks alf.. that worked for me.. sorry i was slow getting back to ya..
0

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
CentOS 6.6 Port opening question 1 135
Cloning a part of HDD MIPS Linux 16 110
Unix / Linux grid computing 5 127
Embeded Linux on Router 9 93
Have you ever been frustrated by having to click seven times in order to retrieve a small bit of information from the web, always the same seven clicks, scrolling down and down until you reach your target? When you know the benefits of the command l…
The purpose of this article is to demonstrate how we can upgrade Python from version 2.7.6 to Python 2.7.10 on the Linux Mint operating system. I am using an Oracle Virtual Box where I have installed Linux Mint operating system version 17.2. Once yo…
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

757 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

21 Experts available now in Live!

Get 1:1 Help Now