【问题标题】:Problem parsing Strings with Russian chars用俄语字符解析字符串的问题
【发布时间】:2021-05-16 10:38:48
【问题描述】:

我正在使用一个旧的objectiveC 例程(我们称之为oldObjectiveCFunction),它解析一个字符串来分析每个字符。分析完字符后,它将字符串分成字符串,并将它们返回到一个名为 *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 代码获取每个 *functions 字符串:

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])" 

【问题讨论】:

  • 如果您尝试在 Objective-C 而不是 Swift 中使用字符串,这些字符串看起来还可以吗?
  • 我猜%c的意思是8位无符号字符(无符号字符);尝试%C 说明符16 位UTF-16 代码单元(unichar)
  • @JosefZ 看起来您对%c%C 的看法是正确的。您应该将其发布为答案,因为 8 位无符号字符不可能包含西里尔字符。
  • 在第 4 行声明 unichar c; 而不是 char c;(对不起,我不会说 swiftObjective-C 所以我我不确定语法是否正确)。

标签: ios objective-c swift string utf-8


【解决方案1】:

你最后的结果并不奇怪。可选项来自string?cString() 函数返回一个 CChar (Int8) 数组。

我认为问题出在此处 - 但我不确定,因为整个事情看起来令人困惑:

[sb appendString:[NSString stringWithFormat:@"%c",c]];

你试过了吗:

[sb appendString: [NSString stringWithCString:c encoding:NSUTF8StringEncoding]];

而不是 stringWithFormat?

(您的评论者提出的 %C 而不是 %c 的解决方案看起来也不错。) - 哎呀 - 刚刚看到您尝试过但没有成功。

【讨论】:

  • 你能分享一下这条线应该是怎样的吗?我不知道如何处理Objective C @Moose
  • 你的代码给了我两个错误:Use of undeclared identifier 'cString' and Unexpected interface name 'NSString': expected expression
  • :D 对不起,我和 swift 混在一起了!我已经习惯了!我修好了
  • 你修好了吗?它给了我完全相同的两个错误,事实上,它是同一行代码,你没有编辑它?
  • 哦 @Moose 现在它已被编辑,但现在给我这个错误:使用未声明的标识符“编码”
【解决方案2】:

分析。对不起,我不会说 swiftObjective-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

解决方案。因此,您需要将所有代码reducing 16 位修复为 8 位:
首先,在第 4 行声明 unichar c; 而不是 char c;
在第 11 行使用 [sb appendString:[NSString stringWithFormat:@"%C",c]];;注意

  • %C 说明符中的拉丁文大写字母 C16 位 UTF-16 代码单元(unichar) 而不是
  • 拉丁文小写字母 C in %c 说明符 8 位无符号字符 (unsigned char);

资源。我的回答基于 SO 对以下问题的回答:

【讨论】:

    猜你喜欢
    • 2016-12-27
    • 2013-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多