0

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' 你是说吗?案子

4

3 回答 3

1

问题

str[i].upcase!将 Array 值中的单个字符变为大写字符。但是,至少在 Ruby 2.7.1 上,它实际上不会更改原始 String 对象的内容,直到您将元素重新分配回要修改的 String 索引。例如:

str[i] = str[i].upcase

但是,上述方法不适用于冻结字符串,这在某些核心方法、库和框架中相当常见。因此,您可能会遇到使用索引分配方法的 FrozenError 异常。

解决方案

解决这个问题的方法不止一种,但一种方法是:

  1. 将您的 String 对象拆分为一个字符数组,
  2. 修改所需索引处的字母,
  3. 将字符重新连接成一个字符串,然后
  4. 将修改后的字符串重新分配给您的原始变量。

例如,显示一些中间步骤:

# 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"

就个人而言,我发现对字符数组进行操作比通过重复分配原始字符串中的索引来进行就地更改更直观且更容易排除故障。此外,它避免了在尝试修改冻结字符串中的索引时引发的异常。但是,您的设计选择可能会有所不同。

于 2020-06-09T13:30:07.123 回答
0

我可以看到你的代码有两个问题......

首先,一个空字符串的长度为 0 所以你想写的是

while str.length == 0

其次,当你...

for i in 0..str.length

您正在迭代字符串长度,包括字符串长度。如果字符串有五个字符,它实际上只有 0 到 4 的有效索引,但您正在迭代 0 到 5。并且str[5]不存在因此返回 nil 并且您不能upcase!对 nil 执行操作。

为了处理这种常见的情况,Ruby 有肚点运算符

for i in 0...str.length

...它将在长度之前的整数处停止,这就是你想要的。

这也更像是红宝石般的事情

(0...str.length).each do |i|
于 2020-06-09T11:46:25.243 回答
0

str[i].upcase返回大写字母,但不修改它。将其分配回字符串以使其工作。

str = 'abcd'
str[2] = str[2].upcase #=> "C"
str #=> "abCd"
于 2020-06-09T11:30:05.170 回答