ramsay
asked on
console input
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?
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?
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.
ASKER
i want an example
ASKER
Adjusted points to 200
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
thanks alf.. i'll look into it now
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
#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
ehm. ****
getch needs conio.h..
forgot to include it.
Nils
getch needs conio.h..
forgot to include it.
Nils
Grretings.
Nils, may work *under windows* (which also has conio.h). But, this is a Linux forum - wrong OS.
Cheers,
alf
Nils, may work *under windows* (which also has conio.h). But, this is a Linux forum - wrong OS.
Cheers,
alf
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
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
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
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
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
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
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
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
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
I'll uncheck the notify.. it looks like I can't help here at all..
bye,
Nils
Ramsay, is the problem closed? If so,
pls. take appropriate action.
Cheers,
alf
ASKER
Thanks alf.. that worked for me.. sorry i was slow getting back to ya..