objective-c - 使用特定编码转换字符串以获得一个字符
问题描述
我正在这个令人沮丧的旅程中试图从 Swift 字符串中获取特定字符。我有一个 Objective-C 函数,比如
- ( NSString * ) doIt: ( char ) c
我想从斯威夫特打电话。
这c
最终被传递给后面的一个 C 函数,该函数在这里进行举重,但是这个函数在c
is
或时被绊倒了A0
。
现在我有两个问题(抱歉)。
我正在尝试使用不同的编码,尤其是
ASCII
变体,希望将
(A0
) 转换为 spcae (20
或 dec 32)。结论似乎是我需要对此进行硬编码,但如果有一种故障安全、非硬编码的方式,我想听听!我真的在为转换本身而苦苦挣扎。如何在 Swift 中使用特定编码访问特定字符?
a) 我可以使用
s.utf8CString[ i ]
但后来我一定会UTF8
。
b)我可以使用类似的东西
let s = "\u{a0}"
let p = UnsafeMutablePointer < CChar >.allocate ( capacity : n )
defer
{
p.deallocate()
}
// Convert to ASCII
NSString ( string : s ).getCString ( p,
maxLength : n,
encoding : CFStringConvertEncodingToNSStringEncoding ( CFStringBuiltInEncodings.ASCII.rawValue ) )
// Hope for 32
let c = p[ i ]
但这似乎有点矫枉过正。字符串被转换为NSString
应用编码,我需要分配一个指针,只是为了得到一个字符。
c) 在这里,Swift String 似乎withCString
是这项工作的人选,但我什至无法编译它。以下是 Xcode 的完成给出的内容,但即使在摆弄了很长时间之后,我仍然被卡住了。
// How do I use this
// ??
s.withCString ( encodedAs : _UnicodeEncoding.Protocol ) { ( UnsafePointer < FixedWidthInteger & UnsignedInteger > ) -> Result in
// ??
}
TIA
解决方案
有两种withCString()
方法:withCString(_:)
使用指向字符串内容的指针调用给定的闭包,表示为以空字符结尾的 UTF-8 代码单元序列。例子:
// An emulation of your Objective-C method.
func doit(_ c: CChar) {
print(c, terminator: " ")
}
let s = "a\u{A0}b"
s.withCString { ptr in
var p = ptr
while p.pointee != 0 {
doit(p.pointee)
p += 1
}
}
print()
// Output: 97 -62 -96 98
这-62 -96
是无间隔字符 U+00A0的 UTF-8 序列的有符号字符表示。C2 A0
如果您只想按顺序遍历字符串的所有 UTF-8 字符,那么您可以简单地使用.utf8
视图。(无符号)UInt8
字节必须转换为相应的(有符号)CChar
:
let s = "a\u{A0}b"
for c in s.utf8 {
doit(CChar(bitPattern: c))
}
print()
我不知道将 U+00A0 转换为“普通”空格字符的方法,因此您必须手动执行此操作。和
let s = "a\u{A0}b".replacingOccurrences(of: "\u{A0}", with: " ")
上述程序的输出将是97 32 98
.
该withCString(encodedAs:_:)
方法使用指向字符串内容的指针调用给定的闭包,表示为以空字符结尾的代码单元序列。例子:
let s = "a\u{A0}b€"
s.withCString(encodedAs: UTF16.self) { ptr in
var p = ptr
while p.pointee != 0 {
print(p.pointee, terminator: " ")
p += 1
}
}
print()
// Output: 97 160 98 8364
此方法可能对您的目的用途有限,因为它只能与UTF8
,UTF16
和一起使用UTF32
。
对于其他编码,您可以使用该data(using:)
方法。它产生一个Data
值,该值是UInt8
(无符号类型)的序列。如上所述,这些必须转换为相应的有符号字符:
let s = "a\u{A0}b"
if let data = s.data(using: .isoLatin1) {
data.forEach {
doit(CChar(bitPattern: $0))
}
}
print()
// Output: 97 -96 98
当然,如果字符串在给定的编码中不可表示,这可能会失败。
推荐阅读
- reactjs - 如何从 redux 存储中获取数据并在 React Native 中的组件中使用它
- vim - VimL:如何将行发送到剪贴板?
- python - 是否可以在 python Altair Heatmap 图中添加黑色网格线?
- html - Angular 中的 Corona 应用程序 - 根据表格值动态字/表格换行 - 无法在 A4 内生成
- python - 如何在 Python 中按分组列查找 ngram
- keystonejs - 如何在 keystonejs 5 中为默认应用程序激活 CORS?
- prolog - Prolog 中的标签变量
- c# - 如何将具有差异内容的 2 个文件合并为 json 对象
- ruby-on-rails - 有没有办法从 Sunspot Solr 查询中获取至少 N 条记录?
- c - 指针 - 在两个文件中读取、写入、复制 c 中的文本