Reputation: 10398
I have this text read into an NSString *responce which I am trying to parse into an array.
total: used: free: shared: buffers: cached:
Mem: 30412800 16805888 13606912 0 1581056 4837376
Swap: 0 0 0
MemTotal: 29700 kB
MemFree: 13288 kB
MemShared: 0 kB
Buffers: 1544 kB
Cached: 4724 kB
SwapCached: 0 kB
Active: 1197 kB
Inactive: 699 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 29700 kB
LowFree: 13288 kB
SwapTotal: 0 kB
SwapFree: 0 kB
Dirty: 0 kB
Writeback: 0 kB
Mapped: 277 kB
Slab: 132 kB
CommitLimit: 14848 kB
Committed_AS: 3400 kB
PageTables: 1567 kB
VmallocTotal: 1048404 kB
VmallocUsed: 17208 kB
VmallocChunk: 1031168 kB
If I read into an array like this, I get over 300 objects in the array!
NSMutableArray *items2 = [NSMutableArray arrayWithArray:[responce componentsSeparatedByString:@" "]];
NSLog(@"count of memory array = %i",[items2 count]);
I add this to try and remove all the blank ones, but still end up with 170.
for (int i=0; i<[items2 count]; i++) {
NSString *str = [items2 objectAtIndex:i];
if([str length]==0 || !str || str==nil) {
[items2 removeObjectAtIndex:i];
}
}
This NSLog statement tells me that most of them are zero length, why where they not removed?
for (int i=0; i<[items2 count]; i++) {
NSLog(@"%i=%@ / length=%d",i,[items2 objectAtIndex:i],[[items2 objectAtIndex:i] length]);
}
Upvotes: 0
Views: 160
Reputation: 55533
It looks like what you really want is a NSDictionary
+ NSScanner
:
NSDictionary *scanString(NSString *str)
{
NSScanner *scanner = [NSScanner scannerWithString:str];
NSMutableDictionary *results = [NSMutableDictionary dictionary];
// read away the first three lines (headers, mem, and swap). If you need this data, parse it here.
for (int i = 0; i < 3; i++) {
[scanner scanUpToString:@"\n" intoString:NULL];
}
NSString *line = nil;
while ([scanner scanUpToString:@"\n" intoString:&line]) {
// trim the line
line = [line stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
// read up to the ':'
int loc = [line rangeOfString:@":"].location;
NSString *key = [line substringToIndex:loc];
// read the value associated with the key
NSString *value = [[line substringFromIndex:loc + 1] stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
value = [value substringToIndex:[value rangeOfString:@" "].location];
[results setObject:value forKey:key];
}
return results;
}
This puts it in a dictionary that you can access by using the following:
NSDictionary *parsed = scanString(response);
NSLog(@"Active Memory: %@", [parsed objectForKey:@"Active"]);
Upvotes: 4
Reputation: 237010
The code you've written treats each individual space as a field separator (giving a huge number of empty fields), while the data you're trying to parse treats any number of spaces as a field separator. You'll want to either use NSScanner or NSRegularExpression to skip arbitrary numbers of spaces.
Upvotes: 1
Reputation: 19469
If you have new line characters between every two items in the string you can use:
NSArray *array = [yourResponseString componentsSeparatedByString:@"\n"];
Also if it is not a newline character which separates two of your components in each of the cases then you need to find a delimiter which separates each of the two elements of your array.
Hope this helps you.
Upvotes: 0
Reputation: 6036
First, investigate using a NSScanner to get your information from your string instance. By default, scanners skip over white space and newline characters.
Second, it appears that the first two lines of your information contain more information than the subsequent lines. Given this inconsistency, you might consider creating a model class to hold your data, rather than a simple array.
Good luck to you in your endeavors.
Upvotes: 0
Reputation: 16725
That is to be expected. Here's what the NSArray Class Reference has to say about componentsSeparatedByString:
The substrings in the array appear in the order they did in the receiver. Adjacent occurrences of the separator string produce empty strings in the result. Similarly, if the string begins or ends with the separator, the first or last substring, respectively, is empty. For example, this code fragment:
P.S. Wouldn't it be easier if you split the input into lines first, and then split by spaces?
Upvotes: 1