10

次に、N個のスペース(この例では12個)を出力しようとします。

NSLog(@"hello%@world", [NSString stringWithCharacters:" " length:12]);

const unichar arrayChars[] = {' '};
NSLog(@"hello%@world", [NSString stringWithCharacters:arrayChars length:12]);

const unichar oneChar = ' ';
NSLog(@"hello%@world", [NSString stringWithCharacters:&oneChar length:12]);

しかし、それらはすべて、次のような奇妙なものを出力しhello ÔÅÓñüÔÅ®Óñü®ÓüÅ®ÓñüÔ®ÓüÔÅ®worldます...「char配列」は「文字列」と同じであり、「文字へのポインタ」と同じだと思いましたか?API仕様では、「Unicode文字のC配列」であると規定されています(Unicodeによると、UTF8ですか?そうである場合は、ASCIIと互換性がある必要があります)...それを機能させる方法と、これら3つの方法が勝った理由動作しませんか?

4

5 に答える 5

17

これにより、必要なものが得られます。

NSLog(@"hello%@world", [@"" stringByPaddingToLength:12 withString:@" " startingAtIndex:0]);
于 2012-05-22T13:23:02.930 に答える
17

%*s幅を指定するために使用できます。

NSLog(@"Hello%*sWorld", 12, "");

参照:

フィールド幅、精度、またはその両方は、アスタリスク('*')で示される場合があります。この場合、int型の引数は、フィールドの幅または精度を提供します。アプリケーションは、フィールド幅または精度、あるいはその両方を指定する引数が、変換される引数(存在する場合)の前にこの順序で表示されることを確認する必要があります。

于 2012-05-22T13:36:16.827 に答える
7

あなたが抱えている問題は、あなたが何をすべきかを誤解していることだと思い+(NSString *)stringWithCharacters:length:ます。文字を繰り返すことは想定されていませんが、代わりに配列から文字列にコピーします。

したがって、あなたの場合、配列には1つの''しかありません。つまり、他の11文字はarrayChars、メモリ内の後続の文字から取得されます。

n個のスペースのパターンを印刷する場合、これを行う最も簡単な方法は、を使用すること-(NSString *)stringByPaddingToLength:withString:startingAtIndex:です。つまり、このようなものを作成します。

NSString *formatString = @"Hello%@World";
NSString *paddingString = [[NSString string] stringByPaddingToLength: n withString: @" " startingAtIndex: 0];
NSLog(formatString, paddingString);
于 2012-05-22T13:23:56.070 に答える
4

これはおそらく最速の方法です。

NSString *spacesWithLength(int nSpaces)
{
    char UTF8Arr[nSpaces + 1];

    memset(UTF8Arr, ' ', nSpaces * sizeof(*UTF8Arr));
    UTF8Arr[nSpaces] = '\0';

    return [NSString stringWithUTF8String:UTF8Arr];
}

現在のコードが機能しない理由+stringWithCharacters:は、配列の長さが1文字しかないのに対し、長さが12文字の配列を想定しているためです{' '}。したがって、修正するには、配列用のバッファを作成する必要があります(この場合、char配列は簡単に作成できますが、配列は使用できないため、charではなく配列を使用します)。unicharmemsetunichar

上で提供した方法は、動的な長さで可能な最速の方法です。GCC拡張機能を使用する意思があり、必要なスペースの固定サイズ配列がある場合は、次のように実行できます。

NSString *spacesWithLength7()
{
    unichar characters[] = { [0 ... 7] = ' ' };
    return [NSString stringWithCharacters:characters length:7];
}

残念ながら、その拡張機能は変数では機能しないため、定数である必要があります。

GCC拡張機能とプリプロセッサマクロの魔法を通して、私はあなたに与えます....リピーター!文字列(または文字)を渡すだけで、後はすべて実行されます。今すぐ購入、たったの19.95ドルで、オペレーターが待機しています!(@JeremyLによって提案されたアイデアに基づく)

// step 1: determine if char is a char or string, or NSString.
// step 2: repeat that char or string
// step 3: return that as a NSString
#define repeat(inp, cnt) __rep_func__(@encode(typeof(inp)), inp, cnt) 

// arg list: (int siz, int / char *input, int n)
static inline NSString *__rep_func__(char *typ, ...)
{
    const char *str = NULL;
    int n;

    {
        va_list args;
        va_start(args, typ);

        if (typ[0] == 'i')
            str = (const char []) { va_arg(args, int), '\0' };
        else if (typ[0] == '@')
            str = [va_arg(args, id) UTF8String];
        else
            str = va_arg(args, const char *);

        n = va_arg(args, int);

        va_end(args);
    }

    int len = strlen(str);
    char outbuf[(len * n) + 1];

    // now copy the content
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < len; j++) {
            outbuf[(i * len) + j] = str[j];
        }
    }

    outbuf[(len * n)] = '\0';
    return [NSString stringWithUTF8String:outbuf];
}
于 2012-05-22T13:21:29.423 に答える
3

このstringWithCharaters:length:メソッドは、C配列の最初の長さの文字を使用してNSString(またはのサブクラスのインスタンス)を作成します。NSString長さに達するまで、指定された文字の配列を繰り返し処理しません。

表示されている出力は、渡された1つのUnicode文字配列の位置から始まる12Unicode文字のメモリ領域です。

これは機能するはずです。

NSLog(@"hello%@world", [NSString stringWithCharacters:"            " length:12]);
于 2012-05-22T13:28:52.863 に答える