sys.stdin.readline () читает без подсказки, возвращая «ничего между»,

У меня есть функция, которая выполняет следующие (между прочим):

userinput = stdin.readline() betAmount = int(userinput) 

Предполагается, что вводят целое число от stdin в виде строки и преобразует его в целое число.

Однако, когда я вызываю функцию, она возвращает один символ новой строки (он даже не дожидается ввода чего-либо).

Раньше в программе я получал некоторый вклад в виде:

 stdin.read(1) 

для захвата одного символа.

Может ли это иметь к этому какое-то отношение? Я как-то пишу символ новой строки для следующей строки stdin?

Как я могу это исправить?

6 Solutions collect form web for “sys.stdin.readline () читает без подсказки, возвращая «ничего между»,”

stdin.read(1) читает один символ из stdin . Если в этот момент было прочитано более одного символа (например, новая строка, следующая за одним символом, который был прочитан), этот символ или символы все равно будут находиться в буфере, ожидающем следующего read() или readline() .

В качестве примера, учитывая rd.py :

 from sys import stdin x = stdin.read(1) userinput = stdin.readline() betAmount = int(userinput) print ("x=",x) print ("userinput=",userinput) print ("betAmount=",betAmount) 

… если я запустил этот скрипт следующим образом (я ввел в 234 ):

 C:\>python rd.py 234 x= 2 userinput= 34 betAmount= 34 

… поэтому сначала выбирается 2, оставляя символ 34 и конечный символ новой строки подбираемым readline() .

Я предлагаю устранить проблему, используя readline() а не read() в большинстве случаев.

Ответ Саймона и Вулкан вместе объясняют, что вы делаете неправильно, и Саймон объясняет, как вы можете исправить это, переработав свой интерфейс.

Но если вам действительно нужно прочитать 1 символ, а затем прочитать 1 строку, вы можете это сделать. Это не тривиально, и это отличается от Windows и всего остального.

На самом деле есть три случая: Unix tty, приглашение Windows DOS или обычный файл (перенаправленный файл / труба) на любой платформе. И вам приходится обращаться с ними по-другому.

Во-первых, чтобы проверить, является ли stdin tty (как для Windows, так и для Unix), вы просто вызываете sys.stdin.isatty() . Эта часть кросс-платформенная.

Для случая non-tty это легко. На самом деле это может сработать. Если это не так, вы можете просто прочитать из небуферизованного объекта под sys.stdin . В Python 3 это просто означает sys.stdin.buffer.raw.read(1) и sys.stdin.buffer.raw.readline() . Однако вы получите закодированные байты, а не строки, поэтому вам нужно будет вызвать .decode(sys.stdin.decoding) по результатам; вы можете обернуть все это функцией.

Однако для случая tty в Windows вход по-прежнему будет зависеть от строки даже в необработанном буфере. Единственный способ обойти это – использовать функции ввода-вывода консоли вместо обычного ввода-вывода файлов. Итак, вместо stdin.read(1) вы используете msvcrt.getwch() .

Для случая tty в Unix вы должны установить терминал в режим raw вместо обычного режима линейной дисциплины. Как только вы это сделаете, вы можете использовать тот же sys.stdin.buffer.read(1) и т. Д., И он будет работать. Если вы готовы сделать это надолго (до конца вашего скрипта), это легко, с tty.setraw функции tty.setraw . Если вы хотите вернуться в режим линейной дисциплины позже, вам нужно будет использовать модуль termios . Это выглядит страшно, но если вы просто termios.tcgetattr(sys.stdin.fileno()) результаты termios.tcgetattr(sys.stdin.fileno()) перед вызовом setraw , тогда сделайте termios.tcsetattr(sys.stdin.fileno(), TCSAFLUSH, stash) Мне нужно узнать, что означают все эти биты.

На обеих платформах микшерный пульт ввода-вывода и режим raw-терминала болезненны. Вы определенно не можете использовать буфер sys.stdin если вы когда-либо делали консольное / сырое чтение; вы можете использовать только sys.stdin.buffer.raw . Вы всегда можете заменить readline , прочитав символ по символу, пока не получите новую строку … но если пользователь попытается отредактировать свою запись, используя обратное пространство, стрелки, командные клавиши в стиле emacs и т. Д., Вы получите все это как необработанные нажатие клавиш, с которыми вы не хотите иметь дело.

 stdin.read(1) 

не будет возвращаться при нажатии одного символа – он будет ждать «\ n». Проблема в том, что второй символ буферизуется в стандартном вводе, а в тот момент, когда вы вызываете другой вход – он немедленно возвращается, потому что он получает свой вход из буфера.

Если вам нужен только один символ, и вы не хотите хранить вещи в буфере, вы можете просто прочитать целую строку и отбросить все, что не нужно.

Заменить:

 stdin.read(1) 

с

 stdin.readline().strip()[:1] 

Это прочитает строку, удалит пробелы и новые строки и просто сохранит первый символ.

Попробуй это …

 import sys buffer = [] while True: userinput = sys.stdin.readline().rstrip('\n') if userinput == 'quit': break else: buffer.append(userinput) 
 import sys userinput = sys.stdin.readline() betAmount = int(userinput) print betAmount 

Это работает на моей системе. Я проверил int ('23 \ n '), что приведет к 23.

  • Python: Postfix stdin
  • Общайтесь с подпроцессом, не дожидаясь завершения подпроцесса в окнах
  • Ввод трубы в программу Python и последующий ввод данных от пользователя
  • Python: прочитайте огромное количество строк из stdin
  • Как создать непрерывное чтение без блокировки из `stdin`?
  • Как читать stdin для 2d массива python целых чисел?
  • Передача данных между Python и C # без записи файла
  • Чтение из файла с sys.stdin в Pycharm
  •  
    Interesting Posts for Van-Lav
    Python - лучший язык программирования в мире.