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/)
python - Read stdin like a dictator - Code Review Stack Exchange
How do you read single chars from stdin in Python - Stack Overflow
Python sys.stdin.read(1) in a while(True) loop consistently executes 1 time getting input and multiple times not getting input - Stack Overflow
python - How do I read from stdin? - Stack Overflow
» pip install readchar
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.
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()).
Use the fileinput module:
import fileinput
for line in fileinput.input():
pass
fileinput will loop through all the lines in the input specified as file names given in command-line arguments, or the standard input if no arguments are provided.
Note: line will contain a trailing newline; to remove it use line.rstrip().
There's a few ways to do it.
sys.stdinis a file-like object on which you can call functionsreadorreadlinesif you want to read everything or you want to read everything and split it by newline automatically. (You need toimport sysfor this to work.)If you want to prompt the user for input, you can use
raw_inputin Python 2.X, and justinputin Python 3.If you actually just want to read command-line options, you can access them via the sys.argv list.
You will probably find this Wikibook article on I/O in Python to be a useful reference as well.
It's simpler:
for line in sys.stdin:
chrCounter += len(line)
The file-like object sys.stdin is automatically iterated over line by line; if you call .readline() on it, you only read the first line (and iterate over that character-by-character); if you call read(), then you'll read the entire input into a single string and iterate over that character-by.character.
The answer from Tim Pietzcker is IMHO the correct one. There are 2 similar ways of doing this. Using:
for line in sys.stdin:
and
for line in sys.stdin.readlines():
The second option is closer to your original code. The difference between these two options is made clear by using e.g. the following modification of the for-loop body and using keyboard for input:
for line in sys.stdin.readlines():
line_len = len(line)
print('Last line was', line_len, 'chars long.')
chrCounter += len(line)
If you use the first option (for line in sys.stdin:), then the lines are processed right after you hit enter.
If you use the second option (for line in sys.stdin.readlines():), then the whole file is first read, split into lines and only then they are processed.