17

Audio Session プログラミングに関連する多くの定数は、実際には 4 文字の文字列です ( Audio Session Services Reference )。などの関数から返されるOSStatus コードにも同じことが当てはまりますAudioSessionGetProperty

問題は、これらのものを箱から出して印刷しようとすると、1919902568 のように見えることです。それを電卓に接続して ASCII 出力をオンにすると、「roch」と表示されますが、プログラムによる方法が必要です。これを行う。

次のブロックを使用して、C 関数の 1 つで限定的な成功を収めました。

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);
}

私がやりたいことは、この機能を現在の機能から抽象化し、他の場所で使用できるようにすることです。やってみた

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

しかし、それは「roch」ではなく「à*€/3íT:ê*€/+€/」を与えてくれます。私の C fu はあまり強力ではありませんが、上記のコードはメモリ アドレスを文字列として解釈しようとしているようです。それとも、エンコードの問題があるのでしょうか? 何か案は?

4

16 に答える 16

19

あなたが話しているタイプは、FourCharCodeで定義されてCFBase.hいるです。と同等OSTypeです。との間で変換する最も簡単な方法はOSType、とNSStringを使用することです。残念ながら、これらの機能はiOSでは利用できません。NSFileTypeForHFSTypeCode()NSHFSTypeCodeFromFileType()

iOSとCocoaで移植可能なコードの場合、私は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));

@()もちろん、さらに簡単に使用するためにマクロにをスローすることもできます。

于 2013-01-08T19:41:00.370 に答える
7

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)
}

この関数は、上記と同じことを 3 分の 1 の時間で実行します。

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)
}

逆の方法は次のようになります。

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)
}
于 2014-09-02T14:22:15.477 に答える
4
char str[5];
str[4] = '\0';
long *code = (long *)str;
*code = 1919902568;
printf("%s\n", str);
于 2013-01-08T19:25:01.687 に答える
4

整数=4バイト=4文字。したがって、整数から文字に変換するには*次のように記述できます。

char st[5] = {0};
st[0] = yourInt & 0xff;
st[1] = (yourInt >> 8) & 0xff;
st[2] = (yourInt >> 16) & 0xff;
st[3] = (yourInt >> 24) & 0xff;

それを元に戻すには:

yourInt = st[0] | (st[1] << 8) | (st[2] << 16) | (st[3] << 24);
于 2013-01-08T19:42:56.020 に答える
3

次のような関数を使用することをお勧めします。

static NSString * NSStringFromCode(UInt32 code)
{
    UInt8 chars[4];
    *(UInt32 *)chars = code;
    for(UInt32 i = 0; i < 4; ++i)
    {
        if(!isprint(chars[i]))
        {
            return [NSString stringWithFormat:@"%u", code];
        }
    }
    return [NSString stringWithFormat:@"%c%c%c%c", chars[3], chars[2], chars[1], chars[0]];
}

これにより、 のような実際の数値である一部の FourCharCode に対してランダムな結果が得られることはなくなりますkCMPixelFormat_32ARGB = 32

于 2014-06-30T07:00:00.413 に答える
3

iOS ではなく macOS 向けに開発している場合、Launch Services にはこのための組み込み関数が既にあります。4cc を NSString として取得するには:

(__bridge_transfer NSString *)UTCreateStringForOSType(fourccInt)
于 2015-10-15T11:47:38.093 に答える
2
  • さまざまなエンディアン アーキテクチャを処理
  • iOSおよびMacOS()
  • わかりやすい
  • 結果の文字列 (はず) は、8 ビット文字であっても OSType と同じです
#import <Cocoa/Cocoa.h>
#import <CoreServices/CoreServices.h> // for EndianU32_NtoB
@implementation NSString (FourCC)

+ (NSString *) stringFromFourCC: (OSType) cccc
{
    NSString * result = nil;
    cccc = EndianU32_NtoB(cccc); // convert to network byte order, if needed
    NSData * data = [NSData dataWithBytes: &cccc length: sizeof(OSType)];
    result = [[NSString alloc] initWithData: data encoding: NSWindowsCP1252StringEncoding]; // lossless 8-bit encoding, could also use NSMacOSRomanStringEncoding
    return result;
}
于 2019-07-08T19:59:41.140 に答える
0

2 つの拡張機能として動作する Swift 2.2 バージョン:

extension String {
    public var fourCharCode:FourCharCode {
        var string = self
        if unicodeScalars.count < 4 {
            string = self + "    "
        }
        string = string.substringToIndex(string.startIndex.advancedBy(4))

        var res:FourCharCode = 0
        for unicodeScalar in string.unicodeScalars {
            res = (res << 8) + (FourCharCode(unicodeScalar) & 255)
        }

        return res
    }
}

extension FourCharCode {
    public var string:String {
        var res = String (UnicodeScalar((self >> 24) & 255))
        res.append(UnicodeScalar((self >> 16) & 255))
        res.append(UnicodeScalar((self >> 8) & 255))
        res.append(UnicodeScalar(self & 255))
        return res
    }
}
于 2016-08-03T11:22:54.617 に答える