我有一个函数,它执行以下内容(以及其他内容):
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
下面的未缓冲对象中读取。在Python3中,这只是指sys.stdin.buffer.raw.read(1)
和sys.stdin.buffer.raw.readline()
。然而,这将获得编码的字节,而不是字符串,因此需要对结果调用.decode(sys.stdin.decoding)
;你可以把这些都封装在一个函数中。
然而,对于Windows上的tty情况,即使在原始缓冲区上,输入仍然是行缓冲的。唯一的解决方法是使用控制台I/O功能,而不是普通的文件I/O。所以,你做的不是stdin.read(1)
,而是msvcrt.getwch()
。
对于Unix上的tty情况,您必须将终端设置为原始模式,而不是通常的行规程模式。一旦你做到了,你就可以使用相同的sys.stdin.buffer.read(1)
,等等,它就会起作用。如果您愿意永久地这样做(直到脚本结束),使用tty.setraw
函数很容易。如果稍后要返回到生产线规程模式,则需要使用termios
模块。这看起来很可怕,但如果你只是在调用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。