NSScanner never reaches "isAtEnd" or don't scann full string - iphone

I've got an issue making scanner working for this particular string.
here comes the code :
tempString = #"30.15 in. Hg (1021 hPa)";
scanner = [NSScanner scannerWithString:tempString]; //setting the scanning location,
[scanner setCharactersToBeSkipped:[[NSCharacterSet characterSetWithCharactersInString:#"0123456789.,-+ "]invertedSet]];
value = 0;
_i = 0;
while([scanner isAtEnd] == NO)
{
[scanner scanFloat:&value];
if(_i == 1)
{
pressure = value;
}
_i++;
}
NSLog(#"pressure = %f hpa",pressure);
this infinity loop...
if I change the string with : tempString = #"30.15 in 8.8 Hg (1021 hPa)";
then it works fine
also if I change with : tempString = #"30.15 in Hg (1021 hPa)";
it also works fine.
the issue comes from the "." (dot)
any clean solution to make this work ?
thanks a lot.

You can check if -scanFloat: returns YES to check if a valid float is scanned. Skip the character if it returns NO.
while (![scanner isAtEnd]) {
if ([scanner scanFloat:&value]) {
if(_i == 1) {
pressure = value;
}
_i++;
} else {
[scanner setScanLocation:[scanner scanLocation] + 1];
}
}

tempString = #"30.15 in. Hg (1021 hPa)";
scanner = [NSScanner scannerWithString:tempString];
[scanner scanUpToString:#"(" intoString:nil];
[scanner scanString:#"(" intoString:nil];
[scanner scanFloat:&value];

Related

Disect an RSS feed

Im having trouble disecting this RSS feed: http://missing.amberalertnederland.nl/nl/index.rss
I want to display the images in a tableview, but the images arent given a seperate tag. How do I extract these images from the description tag? Scan for < and > ?
answer:
- (NSString *)getImage:(NSString *)imageString{
NSString *urlImage = nil;
NSScanner *scanner = [NSScanner scannerWithString:imageString];
[scanner scanUpToString:#"src=\"" intoString:nil];
if (![scanner isAtEnd]) {
[scanner scanString:#"src=\"" intoString:nil];
NSString *urlImage = nil;
[scanner scanUpToString:#"\"" intoString:&urlImage];
if (![scanner isAtEnd]) {
NSLog(#"%#", urlImage);
}
}
return urlImage;
}
Yes, use NSScanner to san up to src=" than scan to the next " and place the result in a temp string.
That should do the trick.

iPhone - NSScanner does not parse

I'm using this method to find the first <> couple into a string (XML content) :
NSScanner* scanner = [NSScanner scannerWithString:contentToParse];
int startPos = 0;
int endPos = 0;
// Open search
if ([scanner scanString:#"<" intoString:nil]) {
startPos = [scanner scanLocation]-1;
NSLog(#"found '<' at pos %i", startPos);
// close search
if ([scanner scanString:#">" intoString:nil]) {
endPos = [scanner scanLocation]-1;
NSLog(#"found '>' at pos %i", endPos);
NSString* tag = [contentToParse substringWithRange:NSMakeRange(startPos, endPos-startPos)];
NSLog(#"Tag found : %#", tag);
}
}
but only "found '<' at pos 0" is logged.
My XML content contains many many <> items...
Why is that method not working ?
scanString:intoString: tries to scan the string parameter at the current location. If such string is not present at the current location, it simply returns NO.
You may want use scanUpToString:intoString: (reference) instead, which scans advancing the scan location until the given string is encountered.
NSScanner *scanner = [NSScanner scannerWithString:contentToParse];
// open search
[scanner scanUpToString:#"<" intoString:nil];
if (![scanner isAtEnd]) {
[scanner scanString:#"<" intoString:nil];
// close search
NSString *tag = nil;
[scanner scanUpToString:#">" intoString:&tag];
if (![scanner isAtEnd]) {
NSLog(#"Tag found : %#", tag);
}
}

nscanner taking value from a string

how can i get the value of pickey from this string.this string as such is stored in coredata and i need to extract the value of pickey.how can i do this using nscanner.which method should i use?
#"http://myserverIP/showpicture.php?email=mymail#yahoo.com&key=442205212&hash=63b201cacb5c07f6adbc8f3dcb408099d3450548&pickey=21342342342342341231"
NSScanner *scanner = [NSScanner scannerWithString:myString];
[scanner scanUpToString:#"pickey=" intoString:NULL];
if ([scanner scanString:#"pickey=" intoString:NULL]) {
long long pickeyValue = 0;
if ([scanner scanLongLong:&pickeyValue]) {
// Successfully found an integer value at this position
...
}
}

How to use NSScanner or componentsSeperatedByString

I have a {"Red","Blue","Green","Yellow"} returned as string. How to process this to add to an array ?
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString* sampleString = #"{\"Red\",\"Blue\",\"Green\",\"Yellow\"}";
NSArray* components = [sampleString componentsSeperatedByString:#"\"{"];
[pool drain];
return 0;
}
Updated Code#
NSString* sampleString = #"{\"Red\",\"Blue\",\"Green\",\"Yellow\"}";
NSMutableArray *rows = [NSMutableArray array];
// Get newline character set
NSMutableCharacterSet *removeCharacterSet = (id)[NSMutableCharacterSet characterSetWithCharactersInString:#"{(,}"];
[removeCharacterSet formIntersectionWithCharacterSet:[[NSCharacterSet whitespaceCharacterSet] invertedSet]];
// Characters that are important to the parser
NSMutableCharacterSet *importantCharactersSet = (id)[NSMutableCharacterSet characterSetWithCharactersInString:#"\""];
[importantCharactersSet formUnionWithCharacterSet:removeCharacterSet];
// Create scanner, and scan string
NSScanner *scanner = [NSScanner scannerWithString:sampleString];
[scanner setCharactersToBeSkipped:nil];
while ( ![scanner isAtEnd] )
{
BOOL insideQuotes = NO;
BOOL finishedRow = NO;
NSMutableArray *columns = [NSMutableArray arrayWithCapacity:10];
NSMutableString *currentColumn = [NSMutableString string];
while ( !finishedRow )
{
NSString *tempString;
if ( [scanner scanUpToCharactersFromSet:importantCharactersSet intoString:&tempString] ) {
[currentColumn appendString:tempString];
}
if ( [scanner isAtEnd] ) {
if ( ![currentColumn isEqualToString:#""] ) [columns addObject:currentColumn];
finishedRow = YES;
}
else if ( [scanner scanCharactersFromSet:removeCharacterSet intoString:&tempString] ) {
if ( insideQuotes ) {
// Add line break to column text
[currentColumn appendString:tempString];
}
else {
// End of row
if ( ![currentColumn isEqualToString:#""] ) [columns addObject:currentColumn];
finishedRow = YES;
}
}
else if ( [scanner scanString:#"\"" intoString:NULL] ) {
if ( insideQuotes && [scanner scanString:#"\"" intoString:NULL] ) {
// Replace double quotes with a single quote in the column string.
[currentColumn appendString:#"\""];
}
else {
// Start or end of a quoted string.
insideQuotes = !insideQuotes;
}
}
else if ( [scanner scanString:#"," intoString:NULL] ) {
if ( insideQuotes ) {
[currentColumn appendString:#","];
}
else {
// This is a column separating comma
[columns addObject:currentColumn];
currentColumn = [NSMutableString string];
[scanner scanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL];
}
}
}
if ( [columns count] > 0 ) [rows addObject:columns];
}
NSLog(#"This String:%#",[rows objectAtIndex:0]);
I got code from http://www.macresearch.org/cocoa-scientists-part-xxvi-parsing-csv-data. Now the output is This String:( Red ), How to get rid of "(" ")" ?
Here's all you need to scan the sample you've provided using an instance of NSScanner:
NSScanner *scanner = [NSScanner scannerWithString:#"{\"Red\",\"Blue\",\"Green\",\"Yellow\"}"];
NSMutableCharacterSet *charactersToSkip = [NSMutableCharacterSet punctuationCharacterSet];
[scanner setCharactersToBeSkipped:charactersToSkip];
NSMutableArray *substrings = [NSMutableArray array];
NSString *substring = #"";
while (![scanner isAtEnd]) {
[scanner scanUpToCharactersFromSet:charactersToSkip intoString:&substring];
[scanner scanCharactersFromSet:charactersToSkip intoString:NULL];
[substrings addObject:substring];
}
NSLog(#"%#", substrings);
Note that if you substituted parens for curly braces, all you'd need to do to create an array of strings from the sample would be:
NSString *sampleString = #"(\"Red\",\"Blue\",\"Green\",\"Yellow\")";
NSArray *strings = [sampleString propertyList];
NSLog(#"%#", strings);
...but I'm not really clear on what you need to accomplish.

NSScanner vs. componentsSeparatedByString

I have a large text file (about 10 MB). In the text file there are values like (without the empty lines between the rows, I couldn't format it here properly):
;string1;stringValue1;
;string2;stringValue2;
;string3;stringValue3;
;string4;stringValue4;
I'm parsing all the 'stringX' values to an Array and the 'stringValueX' to another string, using a pretty ugly solution:
words = [rawText componentsSeparatedByString:#";"];
NSEnumerator *word = [words objectEnumerator];
while(tmpWord = [word nextObject]) {
if ([tmpWord isEqualToString: #""] || [tmpWord isEqualToString: #"\r\n"] || [tmpWord isEqualToString: #"\n"]) {
// NSLog(#"%#*** NOTHING *** ",tmpWord);
}else { // here I add tmpWord the arrays...
I've tried to do this using NSScanner by following this example: http://www.macresearch.org/cocoa-scientists-part-xxvi-parsing-csv-data
But I received memory warnings and then it all crashed.
Shall I do this using NSScanner and if so, can anyone give me an example of how to do that?
Thanks!
In most cases NSScanner is better suited than componentsSeparatedByString:, especially if you are trying to preserve memory.
Your file could be parsed by a loop like this:
while (![scanner isAtEnd]) {
NSString *firstPart = #"";
NSString *secondPart = #"";
[scanner scanString: #";" intoString: NULL];
[scanner scanUpToString: #";" intoString: &firstPart];
[scanner scanString: #";" intoString: NULL];
[scanner scanUpToString: #";" intoString: &secondPart];
[scanner scanString: #";" intoString: NULL];
// TODO: add firstPart and secondPart to your arrays
}
You probably need to add error-checking code to this in case you get an invalid file.
You should use fast enumeration. It's far better than the one using objectEnumerator. Try this
for (NSString *word in words) {
// do the thing you need
}