Does one have to use curses to read single characters from keyboard?

Barry Scott barry at barrys-emacs.org
Sun Dec 11 17:22:45 EST 2022



> On 11 Dec 2022, at 18:50, Chris Green <cl at isbd.net> wrote:
> 
> My solution in the end was copied from one I found that was much
> simpler and straightforward than most.  I meant to post this earlier
> but it got lost somewhere:-
> 
>    import sys, termios, tty
>    #
>    #
>    # Read a single character from teminal, specifically for 'Y/N' 
>    #
>    fdInput = sys.stdin.fileno()
>    termAttr = termios.tcgetattr(0)
>    #
>    #
>    # Get a single character, setcbreak rather than setraw meands CTRL/C
>    etc. still work
>    #
>    def getch():
>        sys.stdout.flush()
>        tty.setcbreak(fdInput)
>        ch = sys.stdin.buffer.raw.read(1).decode(sys.stdin.encoding)

Will not work for uncode code points above 255.

This is what happened when I typed € key:

:>>> a.getch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/private/var/folders/ll/08dwwqkx6v9bcd15sh06x14w0000gn/T/a.py", line 15, in getch
    ch = sys.stdin.buffer.raw.read(1).decode(sys.stdin.encoding)
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 0: unexpected end of data

You would need to have a loop that collected all the utf-8 bytes of a single code point.
You can to look at the first byte of know if the utf-8 is 1, 2, 3 or 4 bytes for a code point.

Barry

>        termios.tcsetattr(fdInput, termios.TCSAFLUSH, termAttr)
>        sys.stdout.write(ch)
>        return ch
>    #
>    #
>    # Get a y or n answer, ignore other characters
>    #
>    def getyn():
>        ch = 'x'
>        while ch != 'y' and ch != 'n':
>            ch = getch().lower()
>        return ch
> 
> So getyn() reads a y or an n, ignores anything else and doesn't wait
> for a return key.  Keyboard input operation is restored to normal
> after doing this. Using tty.setcbreak() rather than tty.setraw() means
> that CTRL/C etc. still work if things go really wrong.

> 
> 
> -- 
> Chris Green
> ·
> -- 
> https://mail.python.org/mailman/listinfo/python-list



More information about the Python-list mailing list