lig*_*ght 16 python stdin python-3.x
我有一个执行以下功能的函数(除其他外):
userinput = stdin.readline()
betAmount = int(userinput)
Run Code Online (Sandbox Code Playgroud)
应该将stdin的输入整数作为字符串并将其转换为整数.
但是,当我调用该函数时,它会返回一个换行符(它甚至不会等我输入任何内容).
在程序的早期,我得到了以下形式的一些输入:
stdin.read(1)
Run Code Online (Sandbox Code Playgroud)
捕获单个字符.
这可能与它有关吗?我是否以某种方式将换行符写入stdin的下一行?
我怎样才能解决这个问题?
Sim*_*mon 22
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)
Run Code Online (Sandbox Code Playgroud)
...如果我按如下方式运行此脚本(我已输入234):
C:\>python rd.py
234
x= 2
userinput= 34
betAmount= 34
Run Code Online (Sandbox Code Playgroud)
...所以2首先拾取它,然后留下34和尾随的换行符readline().
我建议使用readline()而不是read()在大多数情况下修复问题.
aba*_*ert 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情况,即使在原始缓冲区上,输入仍将是行缓冲.解决此问题的唯一方法是使用控制台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风格的命令键等来编辑他的条目,那么你将获得所有这些作为原始的按键,你不想处理.
| 归档时间: |
|
| 查看次数: |
114666 次 |
| 最近记录: |