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:应该做什么。它不应该重复字符,而是将它们从数组复制到字符串中。

因此,在您的情况下,数组中只有一个 ' ',这意味着其他 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:需要一个长度为 12 个字符的数组,而您的数组的长度只有 1 个字符{' '}。因此,要修复,您必须为您的数组创建一个缓冲区(在这种情况下,我们使用char数组,而不是 a unichar,因为我们可以轻松地memset使用 char 数组,但不能使用unichar数组)。

我上面提供的方法可能是动态长度可能最快的方法。如果你愿意使用 GCC 扩展,并且你需要一个固定大小的空间数组,你可以这样做:

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

不幸的是,该扩展不适用于变量,因此它必须是一个常量。

通过 GCC 扩展和预处理器宏的魔力,我给你.... REPEATENATOR!只需传入一个字符串(或一个字符),剩下的就交给它了!现在购买,仅需$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 字符数组的位置开始的 12 个 Unicode 字符长的内存区域。

这应该有效。

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