我使用的是一个旧的objectiveC例程(让我们称之为oldObjectiveCFunction),它解析分析每个字符的字符串。在分析完字符后,它将该String划分为Strings,并将它们返回到一个名为*functions的数组中。这是一个超级精简的示例,说明旧函数是如何进行字符串解析的:
NSMutableArray *functions = [NSMutableArray new];
NSMutableArray *components = [NSMutableArray new];
NSMutableString *sb = [NSMutableString new];
char c;
int sourceLen = source.length;
int index = 0;
while (index < sourceLen) {
c = [source characterAtIndex:index];
//here do some random work analyzing the char
[sb appendString:[NSString stringWithFormat:@"%c",c]];
if (some condition){
[components addObject:(NSString *)sb];
sb = [NSMutableString new];
[functions addObject:[components copy]];
}
}
稍后,我将使用Swift代码获得每个字符串的*函数:
let functions = oldObjectiveCFunction(string) as? [[String]]
functions?.forEach({ (function) in
var functionCopy = function.map { $0 }
for index in 0..<functionCopy.count {
let string = functionCopy[index]
}
}
问题是,它与普通字符串完美配合,但如果字符串包含俄语名称,比如
РАЦИОН
输出,即我的let string
变量的内容,是这样的:
u{10}&u{18}u{1e}u{1d}
我怎么能得到相同的俄罗斯字符串而不是那个?
我试过这样做:
let string2 = String(describing: string?.cString(using: String.Encoding.utf8))
但它返回了更奇怪的结果:
"Optional([32, 16, 38, 24, 30, 29, 0])"
分析。对不起,我不会说swift或Objective-C,所以下面的例子是用Python给出的;然而,第4列和第5列(unicode减少到8位)会让人想起问题中的奇怪的数字。
for ch in 'РАЦИОН':
print(ch, # character itself
ord(ch), # character unicode in decimal
'{:04x}'.format(ord(ch)), # character unicode in hexadecimal
(ord(ch)&0xFF), # unicode reduced to 8-bit decimal
'{:02x}'.format(ord(ch)&0xFF)) # unicode reduced to 8-bit hexadecimal
Р 1056 0420 32 20 А 1040 0410 16 10 Ц 1062 0426 38 26 И 1048 0418 24 18 О 1054 041e 30 1e Н 1053 041d 29 1d
解决方案。因此,您需要修复代码中的所有问题,将16位缩减为8位:
首先,在第4行声明unichar c;
而不是,char c;
并在第11行使用[sb appendString:[NSString stringWithFormat:@"%C",c]];
;纸币
%C
说明符中的- 拉丁文大写字母C而不是
%c
说明符中的拉丁文小写字母C8位无符号字符(无符号字符)
资源。我的答案是基于SO对以下问题的回答:
- 支持哪些Swift String格式说明符
- objective-c-char和unichar之间的区别
您的最后一个结果并不奇怪。optional来自string?
,cString()
函数返回一个CChar(Int8)数组。
我认为问题来自这里,但我不确定,因为整个事情看起来很混乱:
[sb appendString:[NSString stringWithFormat:@"%c",c]];
你试过了吗:
[sb appendString: [NSString stringWithCString:c encoding:NSUTF8StringEncoding]];
而不是字符串WithFormat?
(你的评论者提出的用%C代替%C的解决方案看起来也是个好主意。