2009-01-07 103 views
3

下面是一段代碼,用於獲取表示命令行的字符串(NSString或NSAttributedString)input並將其解析爲兩個字符串,命令cmd和參數args:這似乎工作,但神奇的字符串是一個非常荒謬的黑客Cocoa中的簡單字符串解析/ Objective-C:將命令行解析爲命令和參數

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 = @""; 

。另外,我一點都不確定自己是否正確地使用autoreleases。

ADDED:該解決方案還應該對初始空白有效。另外,我最初有一個叫做inputinStr的輸入字符串。對不起,這個混亂。

ADDED:我相信上面的代碼得到正確的答案,迄今爲止的答案是,參數不應該有任何初始空白。

回答

10
NSString *cmd; 
NSScanner *scanner = [NSScanner scannerWithString:[inStr string]]; 
[scanner scanUpToCharactersFromSet:[NSCharacterSet 
            whitespaceAndNewlineCharacterSet] 
         intoString:&cmd]; 
NSString *args = [[scanner string] substringFromIndex:[scanner scanLocation]]; 

你自動釋放都行,但首先分配字符串是不必要的,因爲NSScanner通過引用返回一個新字符串。由於默認情況下NSScanner的charactersToBeSkipped包含空白字符,因此不應該被初始空白字符絆倒。

5

是這樣的嗎?

int index = [input rangeOfString:@" "].location; 
NSString *cmd = [input substringToIndex:index]); 
NSString *args = [input substringFromIndex:index + 1]); 
+0

甜!我知道它應該非常簡單。謝謝!我想我們的兩個解決方案對初始空白都不夠健壯,呃?是否有一個簡單的「修剪」功能?另外,在你的解決方案中,沒有新的內存被分配,對嗎? – dreeves 2009-01-07 22:10:05

3

你提到的autoreleases實際上沒有任何意義,你所做的只是創建一個可以自動釋放的可變副本(NSMutableString *),但是因爲你將它轉換爲NSString *,所以沒有實際的區別只是說cmd = input;。即使這不是args所需要的,因爲NSScanner會覆蓋那裏的東西。

rangeOfString:會的工作,如果你想要走這條路線,你可以使用的NSString的stringByTrimmingCharactersInSet方法修剪領先空格(我也測試,以確保這兩個參數和命令存在,否則你會得到一個錯誤)。我想要做的是使用NSString componentsSeparatedByCharactersInSet:方法。這會給你一個NSArray對象,其中包含命令和每個參數在一個單獨的索引中。

0

如果要將字符串擴展爲像「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;   
}