在用户输入有效的红宝石输入之前,如何请求用户输入?

时间:2019-01-27 02:14:15

标签: ruby while-loop

这是一个问题,他们要求我添加一个附加的if语句,以在用户未输入任何内容时再次提示用户输入。

我尝试使用while循环,但仍然无法解决问题

print "please enter a sentence with a letter s"

while user_input = gets.chomp.downcase! 
  case user_input
  when user_input.include? "s"
    user_input.gsub(/s/,"th")
    print "Daffy Duck says #{user_input}"
    break
  else
    print "please enter a sentence with a letter s"
  end 

我希望“请输入带有字母s的句子”会一直循环播放,直到用户输入字母“ s”为止。

3 个答案:

答案 0 :(得分:3)

我的理解是,用户输入的句子直到包含"s""S"为止,然后采取某种措施,程序终止。

我们来看看您拥有的东西。

print "Please enter a sentence with a letter s"

我认为您想要的是puts,它添加了换行符,而不是print,而不是换行符。

while user_input = gets.chomp.downcase!

假设用户输入"Cat"(即使不是句子),然后按Enter键,然后

str0 = gets
  #=> "Cat\n"
str1 = str0.chomp
  #=> "Cat"
user_input = str1.downcase!
  #=> "cat"
str1
  #=> "cat"
user_input
  #=> "cat"

所以我们有

while "cat"

由于"cat"既不是false也不是nil(唯一的逻辑false对象),因此与

相同
while true

因此执行将移至while循环内的第一条语句。假设用户输入"cat"并按Enter键。然后

str0 = gets
  #=> "cat\n"
str1 = str0.chomp
  #=> "cat"
user_input = str1.downcase!
  #=> nil
str1
  #=> "cat"
user_input
  #=> nil

因此该程序将不会进入while循环!您问如何"cat".downcase返回nil?查看String#downcase!的文档。它显示如果没有小写字符,则返回nil。 Ruby有许多相同的方法:如果接收者未更改,则返回nil。 (在您的教育阶段,请不要偏向于“为什么”。)目前,建议您避免使用 bang 方法(以"!"结尾)。

类似地,如果用户未输入任何内容并按Enter,则

str1 = "\n".chomp
  #=> "" (an empty string)
user_input = str1.downcase
  #=> nil

"".downcase!返回nil的原因与"cat".downcase!相同。

我想你在下面是什么

user_input = gets.chomp
while !user_input.match?(/s/i)

/s/i是用于确定字符串包含"s"还是"S"的正则表达式。 i中的/i case-indifference 修饰符。 (可以改写while user_input !~ /s/i。)

while循环中的第一条语句是

  case user_input

case有一个自变量(此处为user_input)时,when语句包含的自变量可能是case自变量的值,例如

  case user_input
  when "call me silly!"
    puts "You are silly"
  when...

您此处未做此操作,因此您希望case单独位于一行上

case
when user_input == ...
  ...
end

但是,这里没有必要在循环内使用case语句或“ if / elsif / else / end”结构,因为我们已经确定user_input不包含“ s”。我们在循环中所需的就是:

while !user_input.match?(/s/i)
  puts "Please enter a sentence with a letter s"
  user_input = gets.chomp
end

在循环终止之后,user_input是包含“ s”的字符串。因此,我们只需要执行以下操作即可。

puts "Daffy Duck says #{user_input}"
  #=> "Quack, quack, quackity-quack, sir"

请注意,您的声明

user_input.gsub(/s/, "s")

将每个“ s”替换为“ s”。 :-)也不需要break关键字。

将所有这些放在一起,您可以编写:

puts "Please enter a sentence with a letter s"
user_input = gets.chomp
while !user_input.match?(/s/i)
  puts "Please enter a sentence with a letter s"
  user_input = gets.chomp
end
puts "Daffy Duck says #{user_input}"

你以为我完蛋了。没那么快!

首先,许多Ruby编码人员都试图避免使用诸如while !user_input.match?(/s/i)之类的否定词(尽管这完全是出于品味)。您可以改写那行

until user_input.match?(/s/i)

一个更重要的问题是代码的复制。您可以通过使用Kernel#loop和关键字break代替whileuntil来改善这一点。

loop do
  puts "Please enter a sentence with a letter s"
  user_input = gets.chomp
  if user_input.match?(/s/i)
    puts "Daffy Duck says #{user_input}"
    break
  end
end

但是,如果我们写了

loop do
  puts "Please enter a sentence with a letter s"
  user_input = gets.chomp
  break if user_input.match?(/s/i)
end
puts "Daffy Duck says #{user_input}"

最后一行会引发异常

NameError (undefined local variable or method `user_input' for main:Object)

因为变量user_input仅在循环内定义。

我通常优先使用loopbreak而不是whileuntil

答案 1 :(得分:1)

您的问题是程序无法正常工作吗?

您想做什么?

please enter a sentence with a letter s: a
please enter a sentence with a letter s: s
Daffy Duck says: s

在这种情况下,

print "please enter a sentence with a letter s: "

while user_input = gets
  user_input.chomp.downcase!
  if user_input.include? "s"
    user_input.gsub(/s/,"s")
    print "Daffy Duck says: #{user_input}"
    return
  else
    print "please enter a sentence with a letter s: "
  end
end

答案 2 :(得分:0)

/ s /之后的i是不区分大小写的搜索。 如果字符串中有s并且我们将其删除,则 原始的不匹配

puts "please enter a sentence with a letter s"
while user_input = gets
  user_input = user_input.chomp
  if user_input != user_input.gsub(/s/i,"")
    puts "Daffy Duck says: #{user_input}"
    break
  else
    puts "please enter a sentence with a letter s"
  end
end

如果找到,则匹配位置将是一个从零开始的整数索引 如果没有匹配项,则为nil

puts "please enter another sentence with a letter s"
while user_input = gets
  user_input = user_input.chomp
  match_location =  user_input =~ /s/i
  if match_location.nil?
    puts "please enter a sentence with a letter s"
  else
    puts "Daffy Duck says: #{user_input}"
    break
  end
end