1

I am trying to loop until user inputs an integer. When user inputs a letter, the following code should print "Think of a number":

print "Think of a number "

while user_input = gets.to_i
  if user_input.is_a? Integer
    puts "your number is #{user_input}"
    break
  else
    print "Think of a number "
  end 
end 

I succeeded with my code when user inputs an integer. However when user inputs a string, the to_i method returns 0, and does not execute the else statement because it is a number.

sawa
  • 165,429
  • 45
  • 277
  • 381
Taj
  • 107
  • 9

4 Answers4

4

The main issue with your code is String#to_i method is omnivorous.

"0".to_i #⇒ 0
"0.1".to_i #⇒ 0
"foo".to_i #⇒ 0

That said, user_input in your code is always integer.

What you probably want is to accept digits only (and maybe a leading minus for negatives.) The only concise way to accept a subset of characters is a regular expression.

# chomp to strip out trailing carriage return
user_input = gets.chomp 

if user_input =~ /\A-?\d+\z/
  ...

The regular expression above means nothing save for digits with optional leading minus.


Or, even better (credits to @Stefan)

if gets =~ /\A-?\d+\Z/
Aleksei Matiushkin
  • 119,336
  • 10
  • 100
  • 160
2

If you only want to accept postive digits, you can use a range:

user_input = gets.chomp 
if ('0'..'9').cover? user_input
Oli Crt
  • 1,123
  • 1
  • 11
  • 13
0

let check below one used Integer(gets.chomp) rescue ''

print "Think of a number "

while user_input = Integer(gets.chomp) rescue ''
  if user_input.is_a? Integer
    puts "your number is #{user_input}"
    break
  else
    print "Think of a number "
  end
end
rahul mishra
  • 1,390
  • 9
  • 16
-1

I came across a similar problem. I ended up doing this:

if user_input.strip == user_input.to_i.to_s
  # More code here!
end

Testing for float would be:

if user_input.strip == user_input.to_f.to_s
  # More code here!
end

Solved my issue. See if it helps.

Vaibhav
  • 628
  • 6
  • 10