Простой анализ строки в Какао / Objective-C: анализ командной строки в команду и аргументы - PullRequest
3 голосов
/ 08 января 2009

Вот фрагмент кода, который принимает строку (NSString или NSAttributedString) input, представляющую командную строку, и разбирает ее на две строки, команду cmd и аргументы args:

NSString* cmd = [[input mutableCopy] autorelease];
NSString* args = [[input mutableCopy] autorelease];
NSScanner* scanner = [NSScanner scannerWithString:[input string]];
[scanner scanUpToCharactersFromSet:[NSCharacterSet 
                                    whitespaceAndNewlineCharacterSet] 
                        intoString:&cmd];
if (![scanner scanUpToString:@"magicstring666" intoString:&args]) args = @"";

Кажется, это работает, но волшебная нить - довольно абсурдный взлом. Кроме того, я совсем не уверен, что с авто-релизами я все делаю правильно.

ДОБАВЛЕНО: решение должно быть устойчивым к начальным пробелам. Кроме того, у меня изначально была строка ввода с именами input и inStr. Извините за эту путаницу.

ДОБАВЛЕНО: Я верю, что приведенный выше код прав, что ответы пока не дают, - аргументы args не должны иметь начальных пробелов.

Ответы [ 4 ]

10 голосов
/ 08 января 2009
NSString *cmd;
NSScanner *scanner = [NSScanner scannerWithString:[inStr string]];
[scanner scanUpToCharactersFromSet:[NSCharacterSet
                                    whitespaceAndNewlineCharacterSet] 
                        intoString:&cmd];
NSString *args = [[scanner string] substringFromIndex:[scanner scanLocation]];

Ваши автоматические выпуски были в порядке, но выделение строк в первую очередь не требовалось, поскольку NSScanner возвращает новую строку по ссылке. Поскольку символы NSScannerToBeSkipped по умолчанию содержат пробелы, он не должен быть отключен начальным пробелом.

5 голосов
/ 08 января 2009

Как то так?

int index = [input rangeOfString:@" "].location;
NSString *cmd = [input substringToIndex:index]);
NSString *args = [input substringFromIndex:index + 1]);
3 голосов
/ 08 января 2009

Упомянутые вами авто-релизы на самом деле не имеют никакого смысла, все, что вы делаете, - это создаете изменяемую копию (NSMutableString *), которая должным образом автоматически высвобождается, но, так как вы приводите ее к NSString *, нет никакой практической разницы, тогда просто говоря cmd = input;. Хотя это и не нужно для аргументов, поскольку NSScanner все равно перезапишет то, что там есть.

rangeOfString: сработает, если вы хотите пойти по этому пути, вы можете обрезать начальные пробелы с помощью метода stringByTrimmingCharactersInSet NSString (я также проверю, чтобы убедиться, что и аргументы, и команда существуют, или вы получите ошибку ). Однако я бы использовал метод NSString componentsSeparatedByCharactersInSet:. Это даст вам объект NSArray, содержащий команду и каждый аргумент в отдельном индексе.

0 голосов
/ 21 декабря 2013

Если вы хотите развернуть строку в полный массив аргументов, таких как ввод для 'main', вы можете использовать wordexp.

#import <wordexp.h>

+ (NSMutableArray*) splitArgumentString:(NSString*)strArgs
{
    wordexp_t expandedArgs;
    NSMutableArray *argArray = [NSMutableArray array];

    if(strArgs != nil && 0 == wordexp([strArgs UTF8String], &expandedArgs, 0))
    {
        for(size_t i = 0; i < expandedArgs.we_wordc; ++i)
        {
            NSString arg = [NSString stringWithCString:expandedArgs.we_wordv[i] encoding:NSUTF8StringEncoding];
            [argArray addObject:arg];
        }
        wordfree(&expandedArgs);
    }
    return argArray;        
}
...