繁体   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