用户输入字符串或整数

时间:2014-05-02 07:43:12

标签: ruby

我试图找出用户是输入字符串还是整数。如果我输入一个具有用户输入要求的固定值,我就能找到它。我无法上课。

这有效:

name = 5 
type = name.class

这不起作用:

print "Enter the value to findout its class "
name = gets
type = name.class
if type == String
  puts "this is a string"
elsif type == Fixnum
  puts "this is a fixnum"
else
  puts "this is unknown type"
end

5 个答案:

答案 0 :(得分:2)

我认为我不得不问你的问题是用户应该如何输入一个字符串?

如果用户输入:

10 #=> Fixnum
1_000_000_000_000_000_000_000_000_000_000_000_000_000_000_000 #=> Bignum
1.0 #=> Float
"hello" #=> String
'hello' #=> String

然后你可以这样做:

def test_input
  input = gets.chomp
  puts eval(input).class
rescue NameError
  puts "Unknown Input Class"
end

这实际上应该适用于所有定义的对象,所以如果你只想捕捉那些你提到的那些:

def test_input
  input = gets.chomp
  klass = eval(input).class
  raise NameError unless [Fixnum, Bignum, Float, String].include?(klass)
  puts klass
rescue NameError
  puts "Unknown Input Class"
end

修改

为了避免直接用户输入使用eval,这是一个漏洞,Gumbo建议改为使用解析器。

$ gem install parser 

#!/usr/bin/ruby
require 'parser/current'

def test_input
  input = Parser::CurrentRuby.parse(gets.chomp)

  puts case input.type
  when :str then "String"
  when :float then "Float"
  when :int 
    eval(input.to_sexp.slice(/\d+/)).class 
    # Yes using eval again to get Fixnum vs Bignum, but this time 
    # we know what the input will be, and that's ok to eval
  else
    "Unknown Input Class"
  end
end

答案 1 :(得分:2)

您可以拨打Kernel#StringKernel#IntegerKernel#Float来查找“有效”类,即您可以将输入转换为的类。

def valid_classes(value)
  classes = []
  classes << String(value) rescue nil
  classes << Integer(value) rescue nil
  classes << Float(value) rescue nil
  classes.map(&:class)
end

valid_classes("foo")                   #=> [String]
valid_classes("123.456")               #=> [String, Float]
valid_classes("123")                   #=> [String, Fixnum, Float]
valid_classes("100000000000000000000") #=> [String, Bignum, Float]

其他符号也被认可:

valid_classes("1_000")                 #=> [String, Fixnum]
valid_classes("1e20")                  #=> [String, Float]
valid_classes("0b111")                 #=> [String, Fixnum]

如果您需要更多控制,请使用正则表达式。

这是一个简单的REPL:

loop do
  print "Enter a value to find out its class: "
  input = gets.chomp
  puts "'#{input}' could be a: #{valid_classes(input).join(', ')}"
end

答案 2 :(得分:1)

正如@ArupRakshit在上面的评论中提到的那样,gets总能找到String

您要做的是获取用户的输入并确定它是什么。

例如,"1"String1Fixnum

[2] pry(main)> "1".class
=> String
[3] pry(main)> 1.class
=> Fixnum

在上面的评论中,您提到gets.to_i会给您一个整数。有一个问题。对于非数字字符串,String#to_i返回0:

[6] pry(main)> gets.to_i
hello
=> 0

[7] pry(main)> "hello".to_i
=> 0

所以基本上你得到一个String并且将确定它可能的类别。

# add more Kernel methods here
POSSIBLE_CLASSES = [Integer, Float, Bignum, String]

str = gets.chomp # chomp gets rid of the \n that gets appended 
                 # to your String because you press enter

# As @Stefan does it, but with meta-programming
POSSIBLE_CLASSES.collect { |p| 
  (Kernel.method(p.name).call(str); p) rescue nil 
}.compact

最后一行的解释:

Kernel.Integer("1")返回1 Kernel.Float("1.0")返回1.0

所以基本上,我想调用一个Kernel的方法,该方法的名称与我的类相同。

Kernel.method( method_name )将方法返回给我,然后我用字符串str。

调用

Kernel.Integer("hello")会抛出ArgumentError;这将被拯救,并将收集零。

基本上,上面的行将遍历可能的类并尝试使用我们从控制台获得的字符串初始化它们。如果没有例外,我们收集课程,否则为零。然后我们压缩数组(删除nils),然后包含'有效'类。

请注意,我们上面的代码只支持Kernel类型,可以轻松调整以支持其他类。

答案 3 :(得分:0)

这个怎么样?

class String
  def is_number?
    true if Float(self) rescue false
  end
end

现在在is_number?

上致电user_input
user_input.is_number?

答案 4 :(得分:0)

(gets.chomp =='0'|| gets.chomp.to_i!= 0)=&gt;输入为true 为整数