Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Objective c 在我的macOS应用程序中,我正在使用UserDefaults dictionaryRepresentation。有时我会得到未知编码的字符串。有什么建议吗?_Objective C_Nsstringencoding - Fatal编程技术网

Objective c 在我的macOS应用程序中,我正在使用UserDefaults dictionaryRepresentation。有时我会得到未知编码的字符串。有什么建议吗?

Objective c 在我的macOS应用程序中,我正在使用UserDefaults dictionaryRepresentation。有时我会得到未知编码的字符串。有什么建议吗?,objective-c,nsstringencoding,Objective C,Nsstringencoding,我正在使用Objective-C应用程序,具体来说,我正在使用以下代码收集NSUserDefaults的字典表示: NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSDictionary *userDefaultsDict = [defaults dictionaryRepresentation]; 在枚举结果dict的键和对象时,有时我会发现一种不透明字符串,如下图所示: 所以这似乎是一个编码问题 如果

我正在使用Objective-C应用程序,具体来说,我正在使用以下代码收集NSUserDefaults的字典表示:

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

NSDictionary *userDefaultsDict = [defaults dictionaryRepresentation];
在枚举结果dict的键和对象时,有时我会发现一种不透明字符串,如下图所示:

所以这似乎是一个编码问题

如果我尝试打印字符串的描述,调试器将正确打印:

Printing description of obj:
tsuqsx
但是,如果我尝试将obj写入文件,或以任何其他方式使用它,我会得到如下不可读的输出:

我希望达到以下目标:

  • 以某种方式检测字符串是否存在编码问题

  • 将字符串转换为UTF8编码,以便在程序的其余部分使用它

  • 非常感谢您的帮助。谢谢

    编辑:非常有可能的解决方案,有助于解释我想做什么。

    在尝试了基于dataUsingEncoding的所有可能的解决方案后,我最终得到了以下解决方案,非常奇怪,但我将其发布在这里,希望它能帮助人们猜测编码以及如何处理无法打印的字符:

    - (BOOL)isProblematicString:(NSString *)candidateString {
    
         BOOL returnValue = YES;
    
         if ([candidateString length] <= 2) {
             return NO;
         }
    
         const char *temp = [candidateString UTF8String];
    
         long length = temp[0];
       
            char *dest = malloc(length + 1);
       
            long ctr = 1;
       
            long usefulCounter = 0;
            for (ctr = 1;ctr <= length;ctr++) {
           
               if ((ctr - 1) % 3 == 0) {
                  memcpy(&dest[ctr - usefulCounter - 1],&temp[ctr],1);
               } else {
                   if (ctr != 1 && ctr < [candidateString length]) {
                       if (temp[ctr] < 0x10 || temp[ctr] > 0x1F) {
                           returnValue = NO;
                       }
               }
                   usefulCounter += 1;
               }
           
           }
        memset(&dest[length],0,1);
        free(dest);
    
        return returnValue;
    }
    
    - (NSString *)utf8StringFromUnknownEncodedString:(NSString*)originalUnknownString {                       
    
        const char *temp = [originalUnknownString UTF8String];
    
        long length = temp[0];
    
        char *dest = malloc(length + 1);
    
        long ctr = 1;
    
        long usefulCounter = 0;
        for (ctr = 1;ctr <= length;ctr++) {
        
            if ((ctr - 1) % 3 == 0) {
                memcpy(&dest[ctr - usefulCounter - 1],&temp[ctr],1);
            } else {
                usefulCounter += 1;
            }
        
        }
        memset(&dest[length],0,1);
    
        NSString *returnValue = [[NSString alloc] initWithUTF8String:dest];
        free(dest);
    
    
        return returnValue;
    }
    
    -(BOOL)isProblematicsString:(NSString*)候选测试环{
    BOOL returnValue=YES;
    
    if([candidateString length]我们所说的字符串来自
    /Library/Preferences/.GlobalPreferences.plist
    (key
    com.apple.preferences.timezone.new.selected\u city

    NSString*city=[[NSUserDefaults standardUserDefaults]
    stringForKey:@“com.apple.preferences.timezone.new.selected_city”];
    NSLog(@“%@”,城市);/^Zt^^]s^]^\u^^V^ u q^]^[s\^W\^Zx\^P
    
    我希望达到以下目标:

  • 以某种方式检测字符串是否存在编码问题
  • 将字符串转换为UTF8编码,以便在程序的其余部分使用它
  • &

    在尝试了所有可能的基于数据的解决方案后,使用加密并返回

    此字符串没有编码问题,像
    \x1a
    \x1c
    ,…这样的字符是有效字符。
    您可以使用ASCII、UTF-8等调用
    dataUsingEncoding:
    ,但所有这些字符仍将保留 显示。它们被称为(或非打印字符)。链接的Wikipedia页面解释了这些字符是什么,以及它们是如何在ASCII、扩展ASCII和unicode中定义的

    您要寻找的是一种如何从字符串中删除控制字符的方法

    删除控制字符 我们可以为新方法创建一个类别:

    @接口NSString(控制字符)
    -(NSString*)stringByRemovingControlCharacters;
    @结束
    @实现NSString(控制字符)
    -(NSString*)stringByRemovingControlCharacters{
    //删除控制字符的TODO
    回归自我;
    }
    @结束
    
    在下面的所有示例中,
    city
    变量是这样创建的

    NSString*city=[[NSUserDefaults standardUserDefaults]
    stringForKey:@“com.apple.preferences.timezone.new.selected_city”];
    
    …并包含
    @“\x1at\x1c\x1ds\x1d\x1cu\x16\x1fq\x1d\x1bs\x17\x1ax\x10”
    。还有所有 以下示例使用以下代码进行了测试:

    NSString*citywhithoutcc=[city-stringByRemovingControlCharacters];
    //tsuqsx
    NSLog(@“%@”,无CC的城市);
    //{length=6,bytes=0x747375717378}
    NSLog(@“%@,[CityWithout CC dataUsingEncoding:NSUTF8StringEncoding]);
    
    拆分并连接 一种方法是利用资源。 有一个 方法(
    NSString
    ),但它仅从开头/结尾删除这些字符, 这不是你想要的。有一个技巧你可以使用:

    -(NSString*)stringByRemovingControlCharacters{
    NSArray*components=[自组件由字符分隔集:NSCharacterSet.controlCharacterSet];
    返回[components componentsJoinedByString:@”“];
    }
    
    它通过控制字符拆分字符串,然后将这些组件连接回来。虽然不是一种非常有效的方法,但它可以工作

    重症监护病房改造 另一种方法是使用ICU变换(请参见)。 有一个 方法(
    NSString
    ),但它只接受预定义的常量。文档说明:

    NSStringTransform
    类型定义的常量提供了基础ICU转换功能提供的功能子集。要应用ICU用户指南中定义的ICU转换,但该转换没有相应的
    NSStringTransform
    常量,请创建
    NSMutableString
    和cal的实例l改为使用
    applyTransform:reverse:range:updatedRange:
    方法

    让我们更新我们的实现:

    -(NSString*)stringByRemovingControlCharacters{
    NSMutableString*result=[self-mutableCopy];
    [结果applyTransform:@“[:Cc:[:Cf:]删除”
    反面:没有
    范围:NSMakeRange(0,self.length)
    更新范围:nil];
    返回结果;
    }
    
    [:Cc://code>表示控制字符,
    [:Cf://code>表示格式字符。两者都表示与前面提到的字符集相同的字符集。文档:

    包含Unicode通用类别Cc和Cf中字符的字符集

    迭代字符
    NSCharacterSet
    也提供了该方法。这里我们需要迭代字符(
    unichar
    )并检查它是否是控制字符

    让我们更新我们的实现:

    -(NSString*)stringByRemovingControlCharacters{
    if(self.length==0){
    回归自我;
    }
    NSU整数长度=self.length;
    unichar字符[长度];
    [自获取字符:字符];
    NSUInteger resultLength=0;
    unichar结果[长度];
    NSCharacterSet*控件
    
    (lldb) p [city description]
    (__NSCFString *) $1 = 0x0000600003f6c240 @"\x1at\x1c\x1ds\x1d\x1cu\x16\x1fq\x1d\x1bs\x17\x1ax\x10"