Here's a link to the ActiveState Recipes site that says how you can read a single character in Windows, Linux and OSX:
getch()-like unbuffered character reading from stdin on both Windows and Unix
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
Answer from tehvan on Stack OverflowHere's a link to the ActiveState Recipes site that says how you can read a single character in Windows, Linux and OSX:
getch()-like unbuffered character reading from stdin on both Windows and Unix
class _Getch:
"""Gets a single character from standard input. Does not echo to the
screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
sys.stdin.read(1)
will basically read 1 byte from STDIN.
If you must use the method which does not wait for the \n you can use this code as suggested in previous answer:
class _Getch:
"""Gets a single character from standard input. Does not echo to the screen."""
def __init__(self):
try:
self.impl = _GetchWindows()
except ImportError:
self.impl = _GetchUnix()
def __call__(self): return self.impl()
class _GetchUnix:
def __init__(self):
import tty, sys
def __call__(self):
import sys, tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin.fileno())
ch = sys.stdin.read(1)
finally:
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
return ch
class _GetchWindows:
def __init__(self):
import msvcrt
def __call__(self):
import msvcrt
return msvcrt.getch()
getch = _Getch()
(taken from http://code.activestate.com/recipes/134892/)
Reading char for char from stdin without waiting for '\n' / new line
Python sys.stdin.read(1) in a while(True) loop consistently executes 1 time getting input and multiple times not getting input - Stack Overflow
How do you read single chars from stdin in Python - Stack Overflow
How would I read a single char at a time from stdin
Yo, I'm trying to read from stdin char for char and then operate on it. Specifically I would like to be able to stop reading before receiving a new line character, however, the while loop will only terminate once both an 'x' and a new line is received.
while (1) {
int ch = getchar();
if (ch == 'x')
break;
}I have a suspicion getchar() is maybe not what I want to use. There are so many ways to read input and I can't seem to find the best way. Here is exactly what I want to do if anyone would be so kind to help me out more generally:
-
read input buffer from stdin char for char until specific char is typed in (input can can be any string).
-
once specific char is typed in -> flush the screen, do some calculations, and continue reading the input buffer.
Thanks!
ยป pip install readchar
Problem is probably due to flushing of stdin since the \n lingers on.
as an alternative, use raw_input
while True:
c = raw_input('please enter a character: ')
print 'you entered', c
For the flushing part, see this
sys.stdin is line-buffered by default i.e., your sys.stdin.read(1) won't return until there is full line in stdin buffer.
It means if you enter a character and hit Enter then after you get the first character with sys.stdin.read(1), there is a newline in the buffer (one or two characters: os.linesep) that are read immediately on the next loop iterations.
You could avoid hitting Enter by reading exactly one character at a time (msvcrt.getch()).
This is because your terminal is in cooked mode. You can use e.g. tty.setcbreak or curses.cbreak to disable the line buffering. This is a Unix thing, not particularly Python specific.
Example:
import sys, tty
tty.setcbreak(sys.stdin.fileno())
Note that this has other effects such as disabling echo and will persist when your program exits. Typically a higher level interface such as a curses context manager is used to handle key parsing (arrow keys, for instance, send escape sequences) and cleanup.
The primary command line tool outside of Python for this is stty.
sys.stdin.read(1) is a correct approach.
Before you hit the enter, there is no input at sys.stdin. That line buffering is performed outside your program and you can do nothing about it if you want to use sys.stdin.