В Objective-C, как распечатать N пробелов? (использование stringWithCharacters)
для вывода 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
... Я думал, что " массив символов "такой же, как" строка "и такой же, как"указатель на символ"? Спецификация API говорит, что это должен быть "массив C символов Unicode" (по Unicode, это UTF8? если это так,то он должен быть совместим с ASCII)... Как заставить его работать и почему эти 3 способа не будут работать?
5 ответов
можно использовать %*s
для указания ширины.
NSLog(@"Hello%*sWorld", 12, "");
ширина поля, или точность, или и то, и другое могут быть обозначены звездочкой ( ' * ' ). В этом случае аргумент типа int предоставляет ширину поля или точность. Приложения должны обеспечивать, чтобы аргументы, указывающие ширина поля, или точность, или и то и другое отображаются в этом порядке перед аргумент, если таковой имеется, подлежит преобразованию.
Это даст вам то, что вы хотите:
NSLog(@"hello%@world", [@"" stringByPaddingToLength:12 withString:@" " startingAtIndex:0]);
Я думаю, что проблема в том, что вы неправильно интерпретируете то, что +(NSString *)stringWithCharacters:length:
что должен делать. Он не должен повторять символы, а вместо этого копировать их из массива в строку.
таким образом, в вашем случае у вас есть только один '' в массиве, то есть остальные 11 символов будут взяты из того, что следует arrayChars
в памяти.
если вы хотите распечатать шаблон из n пробелов, самый простой способ сделать это - использовать -(NSString *)stringByPaddingToLength:withString:startingAtIndex:
, i.e создание чего-либо вроде этого.
NSString *formatString = @"Hello%@World";
NSString *paddingString = [[NSString string] stringByPaddingToLength: n withString: @" " startingAtIndex: 0];
NSLog(formatString, paddingString);
это, вероятно, самый быстрый метод:
NSString *spacesWithLength(int nSpaces)
{
char UTF8Arr[nSpaces + 1];
memset(UTF8Arr, ' ', nSpaces * sizeof(*UTF8Arr));
UTF8Arr[nSpaces] = '';
return [NSString stringWithUTF8String:UTF8Arr];
}
почему ваш текущий код не работает, потому что +stringWithCharacters:
ожидает массив с длиной символов 12, в то время как Ваш массив только 1 символ {' '}
. Итак, чтобы исправить, вы должны создать буфер для своего массива (в этом случае мы используем char
массив, а не unichar
, потому что мы можем легко memset
массив символов, но не 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), '' };
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)] = '';
return [NSString stringWithUTF8String:outbuf];
}
на stringWithCharaters:length:
способ делает NSString
(или экземпляр подкласса NSString
), используя первые символы длины в массиве C. Он не выполняет итерацию по заданному массиву символов, пока не достигнет длины.
вывод, который вы видите, - это область памяти 12 символов Юникода, начинающаяся с местоположения переданного массива символов Юникода 1.
это должно работать.
NSLog(@"hello%@world", [NSString stringWithCharacters:" " length:12]);