簡體   English   中英

sys.stdin.readline()讀取沒有提示,返回'之間沒有'

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM