sys.stdin.readline()读取没有提示,返回'之间没有'

时间:2014-01-13 08:27:43

标签: python python-3.x stdin

我有一个执行以下操作的函数(其中包括):

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

应该将stdin的输入整数作为字符串并将其转换为整数。

但是,当我调用该函数时,它会返回一个换行符(它甚至不会等我输入任何内容)。

在程序的早期,我得到了以下形式的一些输入:

stdin.read(1)

捕捉单个角色。

这可能与它有关吗?我是否以某种方式将换行符写入stdin的下一行?

我该如何解决这个问题?

6 个答案:

答案 0 :(得分:21)

stdin.read(1)stdin读取一个字符。如果在该点读取多个字符(例如,读入的一个字符后面的换行符),那么该字符仍将在缓冲区中等待下一个read()或{{ 1}}。

例如,给定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()来解决问题。

答案 1 :(得分:11)

Simon的回答和Volcano一起解释了你做错了什么,Simon解释了如何通过重新设计你的界面来解决它。

但如果你真的需要来读取1个字符,然后再读取1行,你就可以做到。这不是微不足道的,而且在Windows与其他所有内容上都有所不同。

实际上有三种情况:Unix tty,Windows DOS提示符或任一平台上的常规文件(重定向文件/管道)。你必须以不同的方式处理它们。

首先,要检查stdin是否为tty(Windows和Unix各种),只需调用sys.stdin.isatty()即可。那部分是跨平台的。

对于非tty案例,这很容易。它实际上可能只是工作。如果没有,您只需从sys.stdin下面的无缓冲对象中读取即可。在Python 3中,这只意味着sys.stdin.buffer.raw.read(1)sys.stdin.buffer.raw.readline()。但是,这将获得编码的字节,而不是字符串,因此您需要在结果上调用.decode(sys.stdin.decoding);你可以把它全部包含在一个函数中。

但是对于Windows上的tty情况,即使在原始缓冲区上,输入仍然是行缓冲的。解决此问题的唯一方法是使用Console I/O函数而不是普通文件I / O.因此,您需要stdin.read(1)而不是msvcrt.getwch()

对于Unix上的tty情况,您必须将终端设置为原始模式而不是通常的线路规则模式。一旦你这样做,你可以使用相同的sys.stdin.buffer.read(1)等,它就会起作用。如果您愿意永久地执行此操作(直到脚本结束),使用tty.setraw功能很容易。如果您想稍后返回线路规则模式,则需要使用termios模块。这看起来很可怕,但是如果你只是在调用termios.tcgetattr(sys.stdin.fileno())之前隐藏setraw的结果,那么执行termios.tcsetattr(sys.stdin.fileno(), TCSAFLUSH, stash),你就不必知道所有那些繁琐的比特是什么意思。

在这两个平台上,混合控制台I / O和原始终端模式都很痛苦。如果你曾经做过任何控制台/原始阅读,你绝对不能使用sys.stdin缓冲区;你只能使用sys.stdin.buffer.raw。您总是可以通过逐个字符来替换readline,直到您获得换行符...但如果用户尝试使用退格键,箭头,emacs样式的命令键等编辑其条目,您将获得所有这些都是原始的按键,你不想处理。

答案 2 :(得分:3)

stdin.read(1)
当你按下一个字符时,

将不会返回 - 它将等待'\ n'。问题是第二个字符在标准输入中缓冲,当你调用另一个输入时 - 它会立即返回,因为它从缓冲区获取输入。

答案 3 :(得分:2)

如果你只需要一个角色并且你不想把东西放在缓冲区中,你可以简单地阅读整行并删除所有不需要的东西。

替换:

def f(): this.type = ???

stdin.read(1)

这将读取一行,删除空格和换行符,并保留第一个字符。

答案 4 :(得分:0)

试试这个......

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

答案 5 :(得分:-3)

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

print betAmount

这适用于我的系统。我检查int('23 \ n')会导致23。