Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot get the correct input using STDIN.gets.chomp() in ruby

Tags:

ruby

stdin

I am following the LearnRubyTheHardWay tutorial and having a difficulty in modifying the exercise 29. Everything works fine if I define the variables like (as in the tutorial):

people = 100000
cats = 34
dogs = 56

However, if I try to get the variables from STDIN like:

puts "How many people are here?"
people = STDIN.gets.chomp()
puts "How many cats?"
cats = STDIN.gets.chomp()
puts "And how many dogs?"
dogs = STDIN.gets.chomp()

The equality operators return false results as if they only do calculate the results using the first two digits of the numbers. So if I type 100000000 to people and 11, 12 or 13 to cats, the methods return "Too many cats.." If I type 150000000 to people and anything <15 to cats, they return "Not many cats.." Additionally I have to modify

dogs += 5

to

dogs += "5"

otherwise I get the following error: in `+': can't convert Fixnum into String (TypeError)

If I leave the double quotes in place and revert to people = 10000 stuff, I get the following error: in `+': String can't be coerced into Fixnum (TypeError)

So to say, I have no problem with the code in the tutorial, just try to learn what causes the errors introduced by the STDIN methods. I looked into the RubyDoc.org, to see whether it is an issue with fixnum, integer or string classes or anything related to chomp or gets methods but couldn't find the reason. I also tried to_i and to_s before or after but didn't get any result.

The full source code of the file is below:

puts "How many people are here?"
people = STDIN.gets
puts "How many cats?"
cats = STDIN.gets
puts "And how many dogs?"
dogs = STDIN.gets

#people = 100000
#cats = 34
#dogs = 56

puts "So, %d people, %d cats and %d dogs, huh?" % [people,cats,dogs]

if people < cats
  puts "Too many cats! The world is doomed!"
end

if people > cats
  puts "Not many cats! The world is saved!"
end

if people < dogs
  puts "The world is drooled on!"
end

if people > dogs
  puts "The world is dry!"
end

dogs += "5"
puts "Now there are #{dogs} dogs."

if people >= dogs
  puts "People are greater than or equal to dogs."
end

if people <= dogs
  puts "People are less than or equal to dogs."
end

if people == dogs
  puts "People are dogs."
end
like image 862
barerd Avatar asked Mar 05 '26 07:03

barerd


1 Answers

The problem is that STDIN.gets returns a string. All the comparison operations will therefore operate on strings. Example:

people = "100000000"
cats = "11"

puts people < cats  # => true!

This is because < will compare the strings lexicographically (and 1000... comes before 11 in the alphabet). There is actually one point in your example that makes it pretty obvious what's going on here:

dogs = STDIN.gets
dogs += "5"

If you input 7 here, it should print out 75. You see, it just concatenates the strings.

How to fix this? Easy, just convert the strings to integers:

puts "How many people are here?"
people = STDIN.gets.to_i
puts "How many cats?"
cats = STDIN.gets.to_i
puts "And how many dogs?"
dogs = STDIN.gets.to_i
like image 200
Niklas B. Avatar answered Mar 08 '26 01:03

Niklas B.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!