iOS/C:将"整数"转换为四个字符串

Spe*_*ams 13 c ios

与音频会话编程相关的许多常量实际上是四字符串(音频会话服务参考).这同样适用于从函数返回的OSStatus代码AudioSessionGetProperty.

问题是,当我尝试打开这些东西时,它们看起来像1919902568.我可以将其插入计算器并打开ASCII输出,它会告诉我"roch",但必须有一个编程方式做这个.

我使用以下块在我的一个C函数中取得了有限的成功:

char str[20];
// see if it appears to be a four-character code
*(UInt32 *) (str + 1) = CFSwapInt32HostToBig(error);
if (isprint(str[1]) && isprint(str[2]) && isprint(str[3]) && isprint(str[4])) {
    str[0] = str[5] = '\'';
    str[6] = '\0';
} else {
    // no, format as integer
    sprintf(str, "%d", (int)error);
}
Run Code Online (Sandbox Code Playgroud)

我想要做的是从当前函数中抽象出这个特性,以便在别处使用它.我试过了

char * fourCharCode(UInt32 code) {
    // block
}
void someOtherFunction(UInt32 foo){
    printf("%s\n",fourCharCode(foo));
}
Run Code Online (Sandbox Code Playgroud)

但这给了我"à*€/3íT:ê*€/ +€/",而不是"roch".我的C fu不是很强大,但我的预感是上面的代码试图将内存地址解释为字符串.或者可能存在编码问题?有任何想法吗?

Rob*_*ier 16

你所谈论的类型是a FourCharCode,定义于CFBase.h.它相当于一个OSType.最简单的方法之间进行转换OSType,并NSString使用NSFileTypeForHFSTypeCode()NSHFSTypeCodeFromFileType().遗憾的是,这些功能在iOS上不可用.

对于iOS和Cocoa-portable代码,我喜欢他的Joachim Bengtsson (加上一点点清理以便于使用):FourCC2Str()NCCommon.h

#include <TargetConditionals.h>
#if TARGET_RT_BIG_ENDIAN
#   define FourCC2Str(fourcc) (const char[]){*((char*)&fourcc), *(((char*)&fourcc)+1), *(((char*)&fourcc)+2), *(((char*)&fourcc)+3),0}
#else
#   define FourCC2Str(fourcc) (const char[]){*(((char*)&fourcc)+3), *(((char*)&fourcc)+2), *(((char*)&fourcc)+1), *(((char*)&fourcc)+0),0}
#endif

FourCharCode code = 'APPL';
NSLog(@"%s", FourCC2Str(code));
NSLog(@"%@", @(FourCC2Str(code));
Run Code Online (Sandbox Code Playgroud)

您当然可以将其@()放入宏中以便更容易使用.

  • `1634039412` 的 `NSFileTypeForHFSTypeCode` 令人烦恼地返回一个 6 长度的 `"\'aevt\'"` ,其中包含单引号:/ (2认同)

j.s*_*com 5

在Swift中你会使用这个函数:

func str4 (n: Int) -> String
{
    var s: String = ""
    var i: Int = n

    for var j: Int = 0; j < 4; ++j
    {
        s = String(UnicodeScalar(i & 255)) + s
        i = i / 256
    }

    return (s)
}
Run Code Online (Sandbox Code Playgroud)

这个函数将在三分之一的时间内完成同样的操作:

func str4 (n: Int) -> String
{
    var s: String = String (UnicodeScalar((n >> 24) & 255))
    s.append(UnicodeScalar((n >> 16) & 255))
    s.append(UnicodeScalar((n >> 8) & 255))
    s.append(UnicodeScalar(n & 255))
    return (s)
}
Run Code Online (Sandbox Code Playgroud)

相反的方式是:

func val4 (s: String) -> Int
{
    var n: Int = 0
    var r: String = ""
    if (countElements(s) > 4)
    {
        r = s.substringToIndex(advance(s.startIndex, 4))
    }
    else
    {
        r = s + "    "
        r = r.substringToIndex(advance(r.startIndex, 4))
    }
    for UniCodeChar in r.unicodeScalars
    {
        n = (n << 8) + (Int(UniCodeChar.value) & 255)
    }

    return (n)
}
Run Code Online (Sandbox Code Playgroud)