[英]sys.stdin.readline() reads without prompt, returning 'nothing in between'
我有一個執行以下功能的函數(除其他外):
userinput = stdin.readline()
betAmount = int(userinput)
應該將stdin的輸入整數作為字符串並將其轉換為整數。
但是,當我調用該函數時,它會返回一個換行符(它甚至不會等我輸入任何內容)。
在程序的早期,我得到了以下形式的一些輸入:
stdin.read(1)
捕獲單個字符。
這可能與它有關嗎? 我是否以某種方式將換行符寫入stdin的下一行?
我怎樣才能解決這個問題?
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()
來解決問題。
Simon的回答和Volcano一起解釋了你做錯了什么,Simon解釋了如何通過重新設計界面來解決它。
但是如果你真的需要讀1個字符,然后讀1行,你就可以做到。 這不是微不足道的,它在Windows上與其他所有內容都不同。
實際上有三種情況:Unix tty,Windows DOS提示符或任一平台上的常規文件(重定向文件/管道)。 你必須以不同的方式處理它們。
首先,要檢查stdin是否為tty(Windows和Unix各種),只需調用sys.stdin.isatty()
。 那部分是跨平台的。
對於非tty案例,這很容易。 它實際上可能只是工作。 如果沒有,您只需從sys.stdin
下的unbuffered對象中讀取sys.stdin
。 在Python 3中,這僅僅意味着sys.stdin.buffer.raw.read(1)
和sys.stdin.buffer.raw.readline()
。 但是,這將獲得編碼的字節,而不是字符串,因此您需要在結果上調用.decode(sys.stdin.decoding)
; 你可以把它全部包含在一個函數中。
但是,對於Windows上的tty情況,即使在原始緩沖區上,輸入仍將是行緩沖。 解決此問題的唯一方法是使用控制台I / O功能而不是普通文件I / O. 因此,您可以使用msvcrt.getwch()
代替stdin.read(1)
msvcrt.getwch()
。
對於Unix上的tty情況,您必須將終端設置為原始模式而不是通常的線路規則模式。 一旦你這樣做,你可以使用相同的sys.stdin.buffer.read(1)
等,它只會工作。 如果你願意永久地這樣做(直到你的腳本結束),使用tty.setraw
函數很容易。 如果您想稍后返回線路規划模式,則需要使用termios
模塊。 這看起來很可怕,但是如果你在調用setraw
之前只setraw
termios.tcgetattr(sys.stdin.fileno())
的結果,那么就做termios.tcsetattr(sys.stdin.fileno(), TCSAFLUSH, stash)
,你不要我必須要了解所有那些繁瑣的比特意味着什么。
在這兩個平台上,混合控制台I / O和原始終端模式都很痛苦。 如果你曾經做過任何控制台/原始閱讀,你絕對不能使用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。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.