2

It seems nsscanner cant do her job, when it scans a dynamically inputting string. Let me first write my codes:

NSString *setext = mySearchBar.text;
NSScanner *scanner = [NSScanner scannerWithString:setext];
NSString *a = @"a";
NSString *aa;
[scanner scanUpToString:a intoString:NULL];
while ([scanner isAtEnd] == NO)
{
    if ( [scanner scanString:a intoString:NULL]);   
    {
        NSLog (@" scan: %@ ", aa);      
    }
}

I have tried these codes in many of methods, but I get same result: the simulator terminated itself without any crash logs, when I write something in the searchbar. mySearchBar is added programmatically and is of UISearchBar class and is linked to self.

When I tried to rewrite setext to searchText in filterContent method for searching and comparing, NSLog shows endless amount of either

  • "scan : MainViewController"

or

  • "scan: (first character I entered)"

and then crashed. MainViewController is of UIViewController class.

I have tried these codes from Apple Documentation;

http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Strings/Articles/Scanners.html :

NSString *string = @"Product: Acme Potato Peeler; Cost: 0.98 73\n\
    Product: Chef Pierre Pasta Fork; Cost: 0.75 19\n\
    Product: Chef Pierre Colander; Cost: 1.27 2\n";

    NSCharacterSet *semicolonSet;
    NSScanner *theScanner;

    NSString *PRODUCT = @"Product:";
    NSString *COST = @"Cost:";

    NSString *productName;
    float productCost;
    NSInteger productSold;

    semicolonSet = [NSCharacterSet characterSetWithCharactersInString:@";"];
    theScanner = [NSScanner scannerWithString:string];

    while ([theScanner isAtEnd] == NO)
    {
        if ([theScanner scanString:PRODUCT intoString:NULL] &&
            [theScanner scanUpToCharactersFromSet:semicolonSet
                                       intoString:&productName] &&
            [theScanner scanString:@";" intoString:NULL] &&
            [theScanner scanString:COST intoString:NULL] &&
            [theScanner scanFloat:&productCost] &&
            [theScanner scanInteger:&productSold])
        {
            NSLog(@"Sales of %@: $%1.2f", productName, productCost * productSold);
        }
    }

and it works perfectly in any method. NSLog of this code showed up once and is perfectly written. But I cant see why this code works, not mine.

My goal is to detect special characters in the searchbar. If text in the searchbar contains such character(s), so I can disable NSDiactricInsensitiveSearch in NSComparisonResult. Then the search results will display words containing special characters which arent part of diactric characters.


EDIT 16 august:

Ok, here are my codes for nscomparisonresult. @JohnBrighton:`s solution works, but nslog came in a for loop and I couldnt click on anything on the app for the first character I enter... If I paste these codes before for loop, then searching doesnt work;

for (mystr in noWords) {
        NSComparisonResult result;
        NSString *string = mySearchBar.text;
        NSRange range = [string rangeOfString:@"ø"];
        if (range.location != NSNotFound) {
            result = [mystr compare:searchText options:(NSCaseInsensitiveSearch) 
                range:NSMakeRange(0, [searchText length])];     
            NSLog (@" detected");
        }   
        else 
            {
                result = [mystr compare:searchText  options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) 
                              range:NSMakeRange(0, [searchText length])];
            NSLog(@"normal");
        }   
    if (result == NSOrderedSame)
        {
        [self.filteredListContent addObject:mystr];
        }
    }

EDIT 17 august, rewrited the codes above, so the whole method is visible:

- (void)filterContentForSearchText:(NSString*)searchText 
{

    for (mystr in noWords) 
     {

        clock_t start = clock(), end;       

        NSComparisonResult result;
        NSString *string = searchText;
        NSRange range = [string rangeOfString:@"æ"];
        NSRange range2 = [string rangeOfString:@"ø"];
        NSRange range3 = [string rangeOfString:@"å"];
        if (range.location != NSNotFound||range2.location != NSNotFound ||range3.location != NSNotFound ) {
            // This means the character has been found.
            // The position is at range.location.

            result = [mystr compare:searchText options:(NSCaseInsensitiveSearch) 
                              range:NSMakeRange(0, [searchText length])];       
        }   
        else {
            result = [mystr compare:searchText options:(NSCaseInsensitiveSearch|NSDiacriticInsensitiveSearch) 
                              range:NSMakeRange(0, [searchText length])];
        }

        end = clock();
        end = ((double)end - start) / CLOCKS_PER_SEC;
        printf("Time taken: %f \n", (double)end);            

    if (result == NSOrderedSame)
        {
        [self.filteredListContent addObject:mystr];
        }
    }   
}

It came up with endless amount of NSLogs showing "Time taken: 0" instead of "Time taken: 0.0000" from your previous code.

wagashi
  • 894
  • 3
  • 15
  • 39

1 Answers1

1

You are trying to print out "aa", which is something you don't want since you just declared it. Initialize it/print something else out, and it'll work.

Edit: here's a good way to detect if |string| contains "!".

NSString *string = @"it works!";
NSRange range = [string rangeOfString:@"!"];
if (range.location != NSNotFound) {
    /* This means the character has been found.
       The position is at range.location. */
}

Edit #2: here's a way to measure the execution time.

#include <time.h>
...
clock_t start = clock(), end;
...[do your tasks]...
end = clock();
end = ((double)end - start) / CLOCKS_PER_SEC;
printf("Time taken: %f\n", end);
JohnBrighton
  • 161
  • 6
  • Can you explain further? Should I write NSString *aa = [NSString init]; ? I tried it, but it raised an NSException. – wagashi Aug 16 '11 at 16:46
  • 1
    @wagashi In the code you posted, you declared NSString *aa without doing anything with it. Why are you trying to print it out? "aa" is a non initialized variable, thus it's empty. Can you explain what are you trying to accomplish with the code? – JohnBrighton Aug 16 '11 at 16:50
  • NSString *productName; inapple sample works. my goal is:to detect special characters in the searchbar. If text in the searchbar contains such character(s), so I can disable NSDiactricInsensitiveSearch in NSComparisonResult. Then the search results will display words containing special characters which arent part of diactric characters. – wagashi Aug 16 '11 at 17:02
  • 1
    If your goal is to detect if the given NSString contains a string, I suggest to use NSString's -rangeOfString:. Take a look at my edited answer. – JohnBrighton Aug 16 '11 at 17:57
  • @wagashi The code you posted is correct. The problem you are experiencing can perhaps be related to: the array you're looping through, or the place where you're calling the code. Try adding NSLog(@"mystr: %@", mystr); and see what happens. Also, what does noWords contain? – JohnBrighton Aug 16 '11 at 19:13
  • noWords contain many lines splitted by /n and NSLog for mystr showed: (going through all lines...). However, I discovered that whenever i use logs, the app goes amok. without logs, it is fine.. thank you very much! – wagashi Aug 16 '11 at 20:20
  • @wagashi Probably the problem is with NSLog's slowness. Glad it works correctly without it anyway! – JohnBrighton Aug 16 '11 at 20:34
  • btw, this solution makes searching very slow. what should i do? do you think nsscanner can make it equally fast or faster? – wagashi Aug 16 '11 at 20:40
  • I changed the variable from mySearchBar.text, which mySearchBar is a global instance, to searchText which is defined inside the method. And I tried it with nsscanner without nslog, it works too! I cant compare time difference, as I see only a slight difference in that nsscanner is a bit slower than using nsrange. Do you know how to find out how much time a set of codes take? – wagashi Aug 16 '11 at 20:52
  • @wagashi Take a look at edit #2. Performance wise, I'd avoid NSScanner, but I haven't really tried measuring the execution time. – JohnBrighton Aug 16 '11 at 21:10
  • thanks for the codes. I wrote my codes in "Do your tasks", but I get feedback: "format '%d' expects type 'int', but argument 2 has type 'clock_t'" on "printf("Time taken: %d \n", end);". I am not sure if I understand it. Anyway whenever I enter something in the searchbar, it shows up endless nslogs of time 0.0000, because it is inside a for loop. What should I do? – wagashi Aug 16 '11 at 22:25
  • 1
    @wagashi I forgot you should cast it. Try with printf("Time taken: %f\n", (double)end); and it'll work fine. Have you put the whole task (the loop) in the right place? Without having the code, it's really difficult to imagine a scenario. – JohnBrighton Aug 16 '11 at 22:52
  • please see my new edit in my question. It is correct that your new and previous codes work properly, because nslogs show up, but it shows up either 0 or 0.0000... – wagashi Aug 16 '11 at 23:46
  • @wagashi You should put the whole loop inside the measurement code. – JohnBrighton Aug 17 '11 at 07:36
  • now it logged once at a time, but nslog showed "Time taken: 0.00000". By the way, what do you mean by "#include "? – wagashi Aug 17 '11 at 08:33
  • @wagashi If the time is 0, then probably the loop is not being executed, perhaps because the array is empty. time.h is needed for the code I posted. – JohnBrighton Aug 17 '11 at 08:53
  • I have included time.h, and tried measuring tableview reloadData in the method- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchString and (array) count in the method - (NSInteger)tableView:(UITableView *)tableView1 numberOfRowsInSection:(NSInteger)section. NSLogs show that array always contains at least some lines. So I still dont understand why time taken still shows 0. – wagashi Aug 17 '11 at 09:14
  • @wagashi let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2565/discussion-between-johnbrighton-and-wagashi) – JohnBrighton Aug 17 '11 at 09:35
  • since you didnt join the chat for almost 2 days, I will continue discussion here. I have tried your time codes for everything, but it still shows 0.0000. I suspect the codes arent written correctly? – wagashi Aug 19 '11 at 00:15
  • I put the time codes around a looong method, and it finally showed up 1.0000, but why only 0 or 1 and nothing after .? – wagashi Aug 19 '11 at 12:05