使用STDIN.gets时出现多行输入问题

看了这个问题后,我有以下代码:
$/ = ""
answer = STDIN.gets
现在,我希望这将允许用户: 输入多行输入,按Ctrl-D终止。 输入单行输入,按Ctrl-D终止。 输入“无”输入,按Ctrl-D终止。 但是,我实际看到的行为是: 用户可以输入多行输入。 除非按两次Ctrl-D,否则用户无法输入单行输入。 如果用户立即按下Ctrl-D,则可以输入“无”输入。 那么,为什么单行情况(即如果用户输入了一些文本但没有换行,然后按Ctrl-D)需要两次按下Ctrl-D?如果用户什么都不输入,为什么它会起作用呢? (我已经注意到,如果他们什么也没输入并且按下Ctrl-D,我就不会得到一个空字符串,但是nil类 - 我试图在结果上调用
.empty?
时发现了这个,因为它突然失败了。如果有的话让它返回一个空字符串的方法,这将是很好的。我更喜欢检查
.empty?
==
,并且不特别想为nil类定义
.empty?
。) 编辑:因为我真的想知道在Ruby中执行此操作的“正确方法”,我将提供200个代表的赏金。我也会接受一些答案,这些答案可以通过合理的“提交”程序进入终端多行输入 - 我将成为'合适'的判断者。例如,我们目前正在使用两个“ n”,但这不合适,因为它会阻止段落并且不直观。     
已邀请:
基本问题是终端本身。查看帖子右侧的许多相关链接。要解决这个问题,您需要将终端置于原始状态。以下在Solaris机器上为我工作:
#!/usr/bin/env ruby
# store the old stty settings
old_stty = `stty -g`
# Set up the terminal in non-canonical mode input processing
# This causes the terminal to process one character at a time
system "stty -icanon min 1 time 0 -isig"
answer = ""
while true
  char = STDIN.getc
  break if char == ?C-d # break on Ctrl-d
  answer += char.chr
end
system "stty #{old_stty}" # restore stty settings
answer
我不确定是否需要存储和恢复stty设置,但我已经看到其他人这样做了。     
从终端设备读取STDIN时,您正在以稍微不同的模式工作,以从文件或管道读取STDIN。 从tty Control-D(EOF)读取时,如果输入缓冲区为空,则只发送EOF。如果它不为空,则将数据返回到读取系统调用但不发送EOF。 解决方案是使用一些较低级别的IO并一次读取一个字符。以下代码(或类似的东西)将做你想要的
#!/usr/bin/env ruby

answer = ""
while true
  begin
    input = STDIN.sysread(1)
    answer += input
  rescue EOFError
    break
  end
end

puts "|#{answer.class}|#{answer}|"
使用各种输入运行此代码的结果如下: - INPUT这是一行< CR>< Ctrl-D> | String |这是一行 | INPUT这是一行< Ctrl-D> | String |这是一行| INPUT<按Ctrl-d取代; |字符串||     

要回复问题请先登录注册