首页 > 解决方案 > 为什么这个块没有修剪字符串

问题描述

我正在尝试以下块从发送的字符串中修剪前导空格:

trimleading := [ :str|
    ch := (str byteAt: 1).          "get first character: ERROR HERE"
    ret := str copyFrom: 1.         "make a copy of sent string"
    [ch = ' '] whileTrue: [         "while first char is space"
        ret := (ret copyFrom: 2).   "copy from 2nd char"
        ch := ret byteAt: 1.        "again test first char"
        ].
    ret                             "value is modified string"
].

('>>',(trimleading value: '    this is a test  '),'<<') displayNl.

它可以正常工作,但不会从发送的字符串中删除前导空格。返回值与发送的字符串相同。

显然,第一个字符ch没有被选中。at:也不能代替byteAt:.

问题出在哪里,如何解决?谢谢。

标签: stringtrimsmalltalkgnu-smalltalk

解决方案


问题是您将第一个元素作为字节(不是字符而是数字)与具有一个空格字符的字符串进行比较。在 Smalltalk 整数中,字符和字符串是不同的,所以你应该与相应的类型进行比较。at:在这种情况下,您可以使用而不是获取字符串的第一个字符byteAt:,或者与空格的 ascii 值(即 32)进行比较,或者Character space asciiValue$ asciiValue。这是一种可能的解决方案:

    trimleading := [ :str | 
    ch := str at: 1.
    ret := str copyFrom: 1 to: str size.
    [ ch = Character space ]
        whileTrue: [ ret := ret copyFrom: 2 to: ret size.
            ch := ret at: 1 ].
    ret ].
    ^ ('>>' , (trimleading value: '    this is a test  ') , '<<')
        displayNl

您可能已经注意到,我更改copyFrom:copyFrom:to:. 这是因为,与人们想象的不同,copyFrom:它不会从传递到字符串末尾的位置复制,而是尝试从另一个对象复制接收者(此行为继承自Object)。

您的代码还有很多其他可能的改进和简化,我将其留给您作为练习。


推荐阅读