Simple string parsing in Cocoa / Objective-C: command line parsing in command and arguments

Here's a piece of code to enter a string (either NSString or NSAttributedString) input , which is a command line and parses it into two lines, the cmd command and args arguments:

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

It seems to work, but the magic line is a rather absurd hack. In addition, I’m not at all sure that I am doing everything correctly with auto implementations.

ADDED: the solution should also be resistant to the original gaps. In addition, I initially had an input string called both input and inStr . Sorry for this confusion.

ADDED: I believe that one of the above rules gives the right to the fact that the answers so far do not correspond to the fact that the arguments should not have leading spaces.

+3
command-line regex objective-c parsing cocoa
Jan 07 '09 at 21:47
source share
4 answers
 NSString *cmd; NSScanner *scanner = [NSScanner scannerWithString:[inStr string]]; [scanner scanUpToCharactersFromSet:[NSCharacterSet whitespaceAndNewlineCharacterSet] intoString:&cmd]; NSString *args = [[scanner string] substringFromIndex:[scanner scanLocation]]; 

Your auto-implementers were fine, but line highlighting was primarily unnecessary, as NSScanner returns a new line by reference. Since NSScannerToBeSkipped characters include spaces by default, it should not be interrupted by leading spaces.

+10
Jan 07 '09 at 22:39
source share

Something like that?

 int index = [input rangeOfString:@" "].location; NSString *cmd = [input substringToIndex:index]); NSString *args = [input substringFromIndex:index + 1]); 
+5
Jan 07 '09 at 21:58
source share

The autorealizers you mentioned really don't make any sense, all you do is create a mutable copy (NSMutableString *) that is auto-implemented correctly, but since you drop it to NSString *, there is no practical difference. saying cmd = input; . Even this is not required for arguments, as NSScanner will overwrite what is there anyway.

rangeOfString: will work if you want to traverse this route, you can trim leading spaces using the NSString stringByTrimmingCharactersInSet method (I would also try to make sure both arguments and command exist, or you get an error message). However, I would use the NSString componentsSeparatedByCharactersInSet: method. This will give you an NSArray object containing the command and each argument in a separate index.

+3
Jan 07 '09 at 23:40
source share

If you want to expand a string into a full array of arguments, such as input to "main", you can use 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; } 
0
Dec 20 '13 at 20:01
source share



All Articles