Swift 为什么退格键的 strcmp returns -92?
Swift why strcmp of backspace returns -92?
我试图检测 UITextfieldDelegate 内部的退格键。
并找到了这个答案。
并且它工作正常。
但是我不知道这个函数里面发生了什么。
let char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\b")
if isBackSpace == -92 {
print("Backspace was pressed")
return false
}
- 不知道为什么退格的cString结果是0。
我可以在 XCode 上进行调试。请查看截图。
- 我不知道为什么退格键的 strcmp 大约为 0(据我在 XCode 调试器上得到的值)和“\b”字符 returns -92
我知道 backspace 的 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
}
让我们稍微分析一下代码和流经该代码的数据:
string
是一个空字符串,因为当您删除一个字符时,文本字段会尝试将其替换为 "nothing"(一个空字符串)
- 由于 #1,
char
在内存中仅保存字符串终止符,即 [=12=]
:[0]
- "\\b"翻译成
\b
字符串,在内存中:[92, 98]
- 由于#2 和#3,
strcmp
returns 0 - 92 => -92。
不确定为什么人们使用此 "algorithm",而他们可以简单地检查 string
参数是否为空。我假设他们首先尝试使用 \b
转义序列,这似乎不是一个有效的转义序列,因此他们添加了一个额外的 \
字符,该字符已编译,但导致转义序列不正确,因为 \
是反斜杠字符的转义序列,导致 b
部分被表示为纯字母。
似乎委托方法没有报告退格,而是要求委托方法对字符串进行操作。检测实际按键可能需要一些 UIEvent
/RunLoop
钩子。
请注意,传递给 textField(_,shouldChangeCharactersIn:,replacementString:)
的空字符串并不总是意味着按下退格键,剪切操作也可能导致将空字符串发送给委托。您可以尝试检查范围并假设按下退格键的范围为 1,但是用户也可以剪切一个字符...
我试图检测 UITextfieldDelegate 内部的退格键。
并找到了这个答案。
并且它工作正常。
但是我不知道这个函数里面发生了什么。
let char = string.cString(using: String.Encoding.utf8)!
let isBackSpace = strcmp(char, "\b")
if isBackSpace == -92 {
print("Backspace was pressed")
return false
}
- 不知道为什么退格的cString结果是0。 我可以在 XCode 上进行调试。请查看截图。
- 我不知道为什么退格键的 strcmp 大约为 0(据我在 XCode 调试器上得到的值)和“\b”字符 returns -92
我知道 backspace 的 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
}
让我们稍微分析一下代码和流经该代码的数据:
string
是一个空字符串,因为当您删除一个字符时,文本字段会尝试将其替换为 "nothing"(一个空字符串)- 由于 #1,
char
在内存中仅保存字符串终止符,即[=12=]
:[0]
- "\\b"翻译成
\b
字符串,在内存中:[92, 98]
- 由于#2 和#3,
strcmp
returns 0 - 92 => -92。
不确定为什么人们使用此 "algorithm",而他们可以简单地检查 string
参数是否为空。我假设他们首先尝试使用 \b
转义序列,这似乎不是一个有效的转义序列,因此他们添加了一个额外的 \
字符,该字符已编译,但导致转义序列不正确,因为 \
是反斜杠字符的转义序列,导致 b
部分被表示为纯字母。
似乎委托方法没有报告退格,而是要求委托方法对字符串进行操作。检测实际按键可能需要一些 UIEvent
/RunLoop
钩子。
请注意,传递给 textField(_,shouldChangeCharactersIn:,replacementString:)
的空字符串并不总是意味着按下退格键,剪切操作也可能导致将空字符串发送给委托。您可以尝试检查范围并假设按下退格键的范围为 1,但是用户也可以剪切一个字符...