2

I am wondering how to read a single (possibly multibyte) character from a file (for example sys.stdin), without having to wait for any further caracters, end of the line or end of the file. The primary use is to be able to read from standard input as soon as a character is available.

I am primarily using python 3.

The following code illustrates a way to do this in C, where the read character is simply printed to standard out again immediately:

#include <stdio.h>
#include <wchar.h>
#include <locale.h>

int main(void)
{
    setlocale(LC_CTYPE, "");
    wint_t wc;
    while ((wc = fgetwc(stdin)) != WEOF)
    {
        fputwc(wc, stdout);
    }
}
Quantumboredom
  • 1,426
  • 11
  • 19

1 Answers1

2

Something like this?

import sys
import functools
for c in iter(functools.partial(sys.stdin.read, 1), ''):
    print(c)
Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
  • 1
    I think OP wants to read characters instead of simple bytes as `read` does. – halex Feb 22 '14 at 15:45
  • From what I can tell this is actually working! But how? From my limited understanding, sys.stdin.read(1) reads a single byte, and that is called until it returns ''. Why does it return '' after reading a (multibyte) character? And how does the "iter" object know how to construct a valid multibyte string from the individual bytes? – Quantumboredom Feb 22 '14 at 16:03
  • 1
    @Quantumboredom `file.read` returns `''` when there's nothing left to read, i.e when at EOF. So, this code reads a single byte from the stdin until EOF. The above code is actually equivalent to: `c = sys.stdin.read(1);while c != '': c = sys.stdin.read(1)` – Ashwini Chaudhary Feb 22 '14 at 16:18
  • @Ashwini Chaudhary Indeed it does, it would appear then that the documentation for the "read" function is incorrect, since it states that the argument is the maximum number of bytes to be read, while this code correctly reads the entire character even when it is larger than 1 byte (like for example '⇶', which is 3 bytes in UTF-8). I suppose the question then is whether it's the documentation or the implementation that is actually in error (i.e., is your solution portably correct, or is it actually working because of a bug in my python interpreter). – Quantumboredom Feb 22 '14 at 17:22