1

I'm running python 2.7 on 64-bit Windows 7.

Here is the code i'm executing:

import sys
while True:
    print 'please enter a character:'
    c = sys.stdin.read(1)
    print 'you entered', str(c)

In the PyDev evironment in eclipse I get the following output for input a and then b.

please enter a character:
a
you entered a
please enter a character:
you entered 
please enter a character:
you entered 

please enter a character:
b
you entered b
please enter a character:
you entered 
please enter a character:
you entered 

please enter a character:

It correctly gets input once and then executes twice skipping user input.

Now when I run the same code in the python terminal for input a and b I get the following output:

enter char
a
you entered a
enter char
you entered

enter char
b
you entered b
enter char
you entered

enter char

This executes once getting user input and once skipping user input.

What would be causing this issue? How do I get Python to read one char at a time in an infinite loop?

craastad
  • 6,222
  • 5
  • 32
  • 46
  • maybe try `sys.stdin.flush()` after you read... maybe – Joran Beasley Mar 17 '13 at 19:19
  • I lied. In PyDev Eclipse calling flush() makes 1 time getting user input and 1 time skipping user input (instead of 2 times). Adding multiple flush() has no other effect. – craastad Mar 17 '13 at 19:21

2 Answers2

3

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

Community
  • 1
  • 1
Fredrik Pihl
  • 44,604
  • 7
  • 83
  • 130
  • 1
    After more testing i figured out '\r\n' was lingering in the buffer. So on the next iteration of the loop '\r' is immediately returned from read(1) and on the next iteration '\n' is immediately returned from read(1). Calling flush() only gets rid of the '\r', but the '\n' still lingers. – craastad Mar 17 '13 at 19:39
2

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()).

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670