如何测试用户是否输入了数字? [重复]

问题描述 投票:0回答:3

我这样做:

puts "What's your number? "
x = gets.to_i
puts x.class

如果用户输入 3,该字符串(输入)将转换为整数。但如果我输入“Charly”,它也会转换为整数。

测试用户是否输入数字的最佳方法是什么?

ruby
3个回答
4
投票

第一个问题:为什么

String#to_i
方法会将空字符串或至少包含一个非数字字符的字符串转换为整数?

这个问题涉及 Ruby 语言的设计,所以必须是 Ruby 修道士——很可能是该语言的发明者松本幸弘“Matz”松本,才能提供明确的答案。

据推测,如果该方法的行为如文档String#to_i中所述,Ruby 编码人员会发现很方便。

僧侣们可以以不同的方式定义该方法,例如,如果在空字符串或包含数字以外的字符的字符串上调用该方法,则会引发异常,但他们没有。

问题 2:测试用户输入的字符串是否包含一位或多位数字(可能带有前导零)而没有其他内容的最佳方法是什么?

有多种方法可以做到这一点,如其他答案中所建议的。如果字符串表示形式是以 10 为基数的整数,那么所有这些都很好(尽管可能需要进行一些小的调整来处理负整数和非负整数的字符串表示形式)。

我将添加一个使用方法 Kernel::Integer 的解决方案,可选地指定数基(例如

base = 8
)并通过
exception: false
1

使用此方法读起来很好,并且在处理十进制以外的数字基数方面比其他方法更灵活。

一些例子:

s = gets.chomp
  #=> "-21"
Integer(s, exception: false) 
  #=> -21
s = gets
  #=> "-21\n"
Integer(s, exception: false) 
  #=> -21
s = gets
s #=> "-21\r\n" (Windows OS)
Integer(s, exception: false) 
  #=> -21
Integer("0x1a")
  #=> 26
Integer("1a", 16)
  #=> 26
Integer("0930", 10)
  #=> 930
Integer("0930", 16)
  #=> 2352
Integer("111", 2)
  #=> 7
Integer("9", exception: false)
  #=> 9
Integer("09", base = 10, exception: false)
  #=> 9 (despite the following example)
Integer("09", exception: false)
  #=> nil (as "09" is not a valid representation of an integer)
Integer("-21.0", exception: false) 
  #=> nil
Integer("-21e3", exception: false)
  #=> nil
Integer("21", base = 2, exception: false)
  #=> nil

1。如果省略

exception: false
或指定
exception: true
,并且字符串不代表整数,则会引发
ArgumentError
异常(除非参数为
nil
,在这种情况下会引发
TypeError
异常) 。正如评论中指出的,要支持 2.7 之前的 Ruby 版本(当添加
exception: false
时),应该写
Integer(str) rescue nil


1
投票

您可以将数字转换回字符串,然后查看它是否与原始输入匹配。

ok = false
puts "Enter a number"
while not ok do
    s = gets.chomp
    if s.to_i.to_s == s then
        entered_number = s.to_i
        ok = true
    else
      warn "Please enter a number"
    end
end
puts "You entered #{entered_number}"

1
投票

您可以使用正则表达式验证输入:

loop do
  x = gets.strip
  p x.match?(/^\d+$/) ? "number" : "not number"
  puts
end

# =>
asdf
"not number"

123
"number"

   321
"number"
© www.soinside.com 2019 - 2024. All rights reserved.