print str[i].upcase 不起作用,我必须将使用索引确定的特定字母大写。有人可以帮助我吗?
def mumble_letters
str = nil
print "Please write a string : "
str = gets.to_str
# puts str.length
while str.length == 1
print "Please write a string : "
str = gets.to_str
end
for i in 0..str.length
print str[i].upcase!
i.times{ print str[i].capitalize}
if i != str.length - 1
print"-"
end
end
end
mumble_letters
我得到的错误是:nil:NilClass (NoMethodError( 的未定义方法"upcase" 你的意思是? 箱
问题
str[i].upcase!
将数组值中的单个字符更改为大写字符。但是,至少在 Ruby 2.7.1 上,它实际上不会更改原始 String 对象的内容,直到您将元素重新分配给要修改的 String 索引。例如:
str[i] = str[i].upcase
但是,上述方法不适用于冻结字符串,这在某些核心方法、库和框架中相当常见。因此,使用索引分配方法时,您可能会遇到 FrozenError 异常。
溶液
解决此问题的方法不止一种,但一种方法是:
- 将字符串对象拆分为字符数组,
- 修改所需索引处的字母,
- 将字符重新连接为单个字符串,然后
- 将修改后的字符串重新分配给原始变量。
例如,显示一些中间步骤:
# convert String to Array of characters
str = "foobar"
chars = str.chars
# contents of your chars Array
chars
#=> ["f", "o", "o", "b", "a", "r"]
# - convert char in place at given index in Array
# - don't rely on the return value of the bang method
# to be a letter
# - safe navigation handles various nil-related errors
chars[3]&.upcase!
#=> "B"
# re-join Array of chars into String
chars.join
#=> "fooBar"
# re-assign to original variable
str = chars.join
str
#=> "fooBar"
如果需要,可以在重新连接元素之前对chars数组的多个索引执行相同的操作。这应该会产生您正在寻找的结果。
更简洁:
str = "foobar"
chars = str.chars
chars[3]&.upcase!
p str = chars.join
#=> "fooBar"
就个人而言,我发现对字符数组进行操作比通过重复分配原始字符串中的索引进行就地更改更直观、更容易进行故障排除。此外,它避免了在尝试修改冻结字符串中的索引时引发的异常。但是,您的设计选择可能会有所不同。
str[i].upcase
返回大写字母,但不就地修改它。将其分配回字符串以使其工作。
str = 'abcd'
str[2] = str[2].upcase #=> "C"
str #=> "abCd"
我可以看到你的代码有两个问题......
首先,空字符串的长度为 0,所以你想写的是
while str.length == 0
其次,当你这样做时...
for i in 0..str.length
您正在迭代到字符串长度,包括字符串长度。 如果字符串有五个字符,则它实际上只有有效的索引 0 到 4,但您正在迭代 0 到 5。 而且str[5]
不存在,所以返回 nil,你不能在 nil 上做upcase!
。
为了处理这种常见情况,Ruby 使用了牛肚点运算符
for i in 0...str.length
。它将在长度之前的整数处停止,这就是您想要的。
它也更像红宝石
(0...str.length).each do |i|