【问题标题】:Swift why strcmp of backspace returns -92?Swift为什么退格的strcmp返回-92?
【发布时间】:2019-01-05 17:39:54
【问题描述】:

我试图检测 UITextfieldDelegate 内的退格键。 并找到了这个答案。 https://stackoverflow.com/a/49294870/911528

而且它工作正常。

但我不知道这个函数内部发生了什么。

let  char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\\b")

if isBackSpace == -92 {
    print("Backspace was pressed")
    return false
}
  1. 我不知道为什么退格的 cString 的结果是 0。 我可以在 XCode 上调试。请检查屏幕截图。

  1. 我不知道为什么退格的 strcmp 大约为 0(据我在 XCode 调试器上得到这个值)和“\b”字符返回 -92

我知道退格的 ascii 代码是 int 类型的“8”,所以我认为上面的函数会像下面的代码。

// I thought this char would be "\b" of type char or 08 of type int
// but XCode give the value 0... I don't know why
let char = string.cString(using: String.Encoding.utf8)!

// as far as I know, strcmp returns positive value for equal values.
let isBackSpace = strcmp(char, "\\b")

// so I thought this would be
if isBackSpace > 0 {
    print("Backspace was pressed")
    return false // or true
}

谁能一步一步解释这段代码? 谢谢。

参考:

https://linux.die.net/man/3/strcmp

https://theasciicode.com.ar/ascii-control-characters/backspace-ascii-code-8.html


现在我可以理解人们为什么使用该代码了, 而且上面的代码不正确。

参考@Cristik 的回答尝试正确编辑。

func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // backspace checking
        if string == "" {
            return true // or false
        }

【问题讨论】:

    标签: swift strcmp uitextfielddelegate backspace


    【解决方案1】:

    让我们稍微分析一下代码和流经该代码的数据:

    1. string 是一个空字符串,因为当您删除一个字符时,文本字段会尝试将其替换为“nothing”(一个空字符串)
    2. 由于#1,char 仅在内存中保存字符串终止符\0[0]
    3. "\\b" 转换为 \b 字符串,在内存中:[92, 98]
    4. 由于 #2 和 #3,strcmp 返回 0 - 92 => -92。

    不确定人们为什么要使用这种“算法”,因为他们可以简单地检查 string 参数的空性。我假设他们首先尝试使用\b 转义序列,这似乎不是一个有效的转义序列,因此他们添加了一个额外的\ 字符,该字符已编译,但导致转义序列不正确,如\\是反斜杠字符的转义序列,导致b 部分被表示为纯字母。

    似乎委托方法没有报告退格,而是要求委托方法对字符串进行操作。检测实际按键可能需要一些 UIEvent/RunLoop 钩子。

    请注意,传递给textField(_,shouldChangeCharactersIn:,replacementString:) 的空字符串并不总是意味着按下退格键,剪切操作也可能导致将空字符串发送给代理。您可以尝试检查范围并假设按下了 1 个退格键,但是用户也可以剪切一个字符...

    【讨论】:

    • 完美答案!多谢!我100%明白你在说什么。因此,我将通过参考您的答案来更新我的代码。
    • @AutumnSky 一些注意事项:不建议将部分答案添加到问题的 SO 实践中,问题和答案部分应用于其预期目的。其次,请查看我今天添加的最后一段,空字符串并不一定意味着按下了退格键。
    • 优秀的答案...我已经使用它将近 2 年了,现在很明显这是一个完全有缺陷的“算法”,它是偶然起作用的......你可以使用“\ \x" 并且它将起作用,因为正如@Cristik 指出的那样,strcmp 仅针对空输入评估“转义序列”的第一个元素
    • 我可以告知,使用:strcmp(char, "x") // x = ASCII 120 然后:如果 isBackSpace == -120 它会起作用...
    猜你喜欢
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-10
    相关资源
    最近更新 更多