Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > Mac OS X Development Forums > Objective-C, Python, Ruby Development

Reply
 
LinkBack Thread Tools Display Modes
Old 04-22-2009, 07:32 PM   #1 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 16
MalSleek is on a distinguished road
Default Scanf'ing for a string to search for within an array object...

Basically, I'd like to ask the user for what he'd like to search for in a particular array (an address book)...

and if he types part of a NAME (ie Mark), the program will search each object in the array (ie name part of address) for that NAME and print the object in the array if it contains it.

So I'm trying to use a scanf ("%@", &theName) where name is an NSString object.

I've tried using a rangeOfString when comparing the object to the string name, but they are "incompatible data types" and the program won't function...

What NS method can I use to search for string contents within an object in an array?

Thanks -

Mal

PS: I'm on chapter 15 exercise 2 of Kochan's Objective-C book - just trying to implement some user interaction to the exercise...
MalSleek is offline   Reply With Quote
Old 04-22-2009, 07:36 PM   #2 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

You should be using rangeOfString (or something similar). Post the code so we can tell you what you did wrong to get that error message.

joe
FlyingDiver is offline   Reply With Quote
Old 04-22-2009, 07:44 PM   #3 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 16
MalSleek is on a distinguished road
Default

Code:
 //Method I'm trying to use

-(AddressCard *) lookup: (NSString *) theName
{
	AddressCard *nextCard;
	NSRange substr;
	
	
	
	int i, elements;
	elements = [book count];
	
	for (i = 0; i<elements; ++i) {
		nextCard = [book objectAtIndex: i];
		
		substr = [nextCard rangeOfString: theName];
		
		if (substr.location != NSNotFound)
			return nextCard;
	}
	
	return nil;
}
Code:
//program - see lookup section
#import "AddressBook.h"
#import <Foundation/NSAutoreleasePool.h>

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSString *aName = @"Julia Kochan";
	NSString *aEmail = @"jewls337@axlc.com";
	NSString *bName = @"Tony Iannino";
	NSString *bEmail = @"tony.iannino@techfitness.com";
	NSString *cName = @"Stephen Kochan";
	NSString *cEmail = @"steve@kochan-wood.com";
	NSString *dName = @"Jamie Baker";
	NSString *dEmail = @"jbaker@kochan-wood.com";
	
	AddressCard *card1 = [[AddressCard alloc] init];
	AddressCard *card2 = [[AddressCard alloc] init];
	AddressCard *card3 = [[AddressCard alloc] init];
	AddressCard *card4 = [[AddressCard alloc] init];
	
	AddressBook *myBook = [AddressBook alloc];
	AddressCard *myCard;
	
	[card1 setName: aName andEmail: aEmail];
	[card2 setName: bName andEmail: bEmail];
	[card3 setName: cName andEmail: cEmail];
	[card4 setName: dName andEmail: dEmail];
	
	myBook = [myBook initWithName: @"Linda's Address Book"];
		
	[myBook addCard: card1];
	[myBook addCard: card2];
	[myBook addCard: card3];
	[myBook addCard: card4];
	
	NSString *nombre;
	
	printf("What's the info you'd like to search for?");
	scanf("%@", &nombre);
	
	[myBook lookup: nombre];
	
	if (myCard != nil)
		[myCard print];
	else
		printf ("Not found!\n");
	
	
	[myBook sort];
	[myBook list];
	
	[card1 release];
	[card2 release];
	[card3 release];
	[card4 release];
	[myBook release];
	[pool release];
	
	return 0;
	
}
MalSleek is offline   Reply With Quote
Old 04-22-2009, 07:56 PM   #4 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

I thought you were using the built-in AddressBook. It appears you're using a custom class. We'll need to see the code for that, but I'm 100% sure the problem is in this line:

Code:
substr = [nextCard rangeOfString: theName];
You can't call rangeOfString on a non-NSString object. You need to be doing something more like:

Code:
substr = [[nextCard name] rangeOfString: theName];
Where the name accessor in AddressBook returns an NSString containing the name field to search in.

joe
FlyingDiver is offline   Reply With Quote
Old 04-22-2009, 09:14 PM   #5 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 16
MalSleek is on a distinguished road
Default

Hmm, I did try that initially and had the same problem...I changed it back to that...here's everything I have and the program generated at the bottom...

AddressCard.h

Code:
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSRange.h>

@interface AddressCard: NSObject
{
NSString *name;
NSString *email;
}

-(void) setName: (NSString *) theName;
-(void) setEmail: (NSString *) theEmail;
-(void) setName: (NSString *) theName andEmail: (NSString *) theEmail;
-(NSComparisonResult) compareNames: (id) element;

-(NSString *) name;
-(NSString *) email;

-(void) dealloc;

-(void) print;

@end
AddressCard.m

Code:
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSRange.h>

@interface AddressCard: NSObject
{
NSString *name;
NSString *email;
}

-(void) setName: (NSString *) theName;
-(void) setEmail: (NSString *) theEmail;
-(void) setName: (NSString *) theName andEmail: (NSString *) theEmail;
-(NSComparisonResult) compareNames: (id) element;

-(NSString *) name;
-(NSString *) email;

-(void) dealloc;

-(void) print;

@end
AddressBook.h

Code:
#import <Foundation/NSArray.h>
#import "AddressCard.h"

@interface AddressBook: NSObject
{
NSString		*bookName;
NSMutableArray	*book;
}

-(AddressBook *) initWithName: (NSString *) name;
-(void) addCard: (AddressCard *) theCard;
-(void) removeCard: (AddressCard *) theCard;
-(AddressCard *) lookup: (NSString *) theName;
-(void) sort;
-(int) entries;
-(void) list;
-(void) dealloc;

@end
AddressBook.m

Code:
#import "AddressBook.h"

@implementation AddressBook;

-(id) initWithName: (NSString *) name
{
	self = [super init];
	
	if (self) {
		bookName = [[NSString alloc] initWithString: name];
		book = [[NSMutableArray alloc] init];
	}
	
	return self;
}

-(void) addCard: (AddressCard *) theCard
{
	[book addObject: theCard];
}

-(void) removeCard: (AddressCard *) theCard
{
	[book removeObjectIdenticalTo: theCard];
}

-(void) sort
{
	[book sortUsingSelector: @selector (compareNames:)];
}

-(AddressCard *) lookup: (NSString *) theName
{
	AddressCard *nextCard;
	NSRange substr;
	
	
	
	int i, elements;
	elements = [book count];
	
	for (i = 0; i<elements; ++i) {
		nextCard = [book objectAtIndex: i];
		
		substr = [[nextCard name] rangeOfString: theName];
		
		if (substr.location != NSNotFound)
			return nextCard;
	}
	
	return nil;
}

-(int) entries
{
	[book count];
}

-(void) list
{
	int i, elements;
	AddressCard *theCard;
	
	printf("\n======== Contents of: %s =========\n", [bookName cString]);
	
	elements = [book count];
	
	for (i = 0; i < elements; ++i) {
		theCard = [book objectAtIndex: i];
		printf("%-20s %-32s\n",[[theCard name] cString], [[theCard email] cString]);
	}
	
	printf("====================================================\n\n");
}

-(void) dealloc
{
	[bookName release];
	[book release];
	[super dealloc];
}

@end
Main.m

Code:
#import "AddressBook.h"
#import <Foundation/NSAutoreleasePool.h>

int main(int argc, char *argv[])
{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
	NSString *aName = @"Julia Kochan";
	NSString *aEmail = @"jewls337@axlc.com";
	NSString *bName = @"Tony Iannino";
	NSString *bEmail = @"tony.iannino@techfitness.com";
	NSString *cName = @"Stephen Kochan";
	NSString *cEmail = @"steve@kochan-wood.com";
	NSString *dName = @"Jamie Baker";
	NSString *dEmail = @"jbaker@kochan-wood.com";
	
	AddressCard *card1 = [[AddressCard alloc] init];
	AddressCard *card2 = [[AddressCard alloc] init];
	AddressCard *card3 = [[AddressCard alloc] init];
	AddressCard *card4 = [[AddressCard alloc] init];
	
	AddressBook *myBook = [AddressBook alloc];
	AddressCard *myCard;
	
	[card1 setName: aName andEmail: aEmail];
	[card2 setName: bName andEmail: bEmail];
	[card3 setName: cName andEmail: cEmail];
	[card4 setName: dName andEmail: dEmail];
	
	myBook = [myBook initWithName: @"Linda's Address Book"];
		
	[myBook addCard: card1];
	[myBook addCard: card2];
	[myBook addCard: card3];
	[myBook addCard: card4];
	
	NSString *nombre;
	
	printf("What's the info you'd like to search for?");
	scanf("%@", &nombre);
	
	[myBook lookup: nombre];
	
	if (myCard != nil)
		[myCard print];
	else
		printf ("Not found!\n");
	
	
	[myBook sort];
	[myBook list];
	
	[card1 release];
	[card2 release];
	[card3 release];
	[card4 release];
	[myBook release];
	[pool release];
	
	return 0;
	
}
Program response after build

Code:
What's the info you'd like to search for?2009-04-22 22:14:11.134 Address Book[198:10b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFString rangeOfString:options:range:locale:]: nil argument'
2009-04-22 22:14:11.136 Address Book[198:10b] Stack: (
    2479034635,
    2415971899,
    2479034091,
    2479034154,
    2423308442,
    2423344392,
    10811,
    9246,
    8434
)

[Session started at 2009-04-22 22:14:11 -0400.]
Loading program into debugger…
GNU gdb 6.3.50-20050815 (Apple version gdb-962) (Sat Jul 26 08:14:40 UTC 2008)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "i386-apple-darwin".Program loaded.
sharedlibrary apply-load-rules all
Attaching to program: `/Users/Mal/Desktop/Address Book/build/Debug/Address Book.app/Contents/MacOS/Address Book', process 198.
(gdb)
Most of this is from the textbook...the only part with errors are the parts I tried to create haha...could it be something to do with the myCard object? I feel like this is doing nothing...

Last edited by MalSleek; 04-22-2009 at 09:17 PM.
MalSleek is offline   Reply With Quote
Old 04-22-2009, 09:41 PM   #6 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

Please post the contents of AddressCard.m. You posted the header file twice.

joe
FlyingDiver is offline   Reply With Quote
Old 04-22-2009, 09:43 PM   #7 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 16
MalSleek is on a distinguished road
Default

AddressCard.m

Code:
#import "AddressCard.h"

@implementation AddressCard;

-(void) setName: (NSString *) theName
{
	[name release];
	name = [[NSString alloc] initWithString: theName];
}

-(void) setEmail: (NSString *) theEmail
{
	[email release];
	email= [[NSString alloc] initWithString: theEmail];
}

-(void) setName: (NSString *) theName andEmail: (NSString *) theEmail
{
	[self setName: theName];
	[self setEmail: theEmail];
}

-(NSComparisonResult) compareNames: (id) element
{
	return [name compare: [element name]];
}

-(NSString *) name
{
	return name;
}

-(NSString *) email
{
	return email;
}

-(void) dealloc
{
	[name release];
	[email release];
	[super dealloc];
}

-(void) print
{
	printf ("====================================\n");
	printf ("|                                  |\n");
	printf ("|  %-31s |\n", [name cString]);
	printf ("|  %-31s |\n", [email cString]);
	printf ("|                                  |\n");
	printf ("|                                  |\n");
	printf ("|                                  |\n");
	printf ("|       O                   O      |\n");
	printf ("====================================\n");
}

@end
ACK - sorry bout that...
MalSleek is offline   Reply With Quote
Old 04-22-2009, 09:43 PM   #8 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

Also, this line:

Code:
	[myBook lookup: nombre];
Needs to be:

Code:
myCard = [myBook lookup: nombre];
joe
FlyingDiver is offline   Reply With Quote
Old 04-22-2009, 09:56 PM   #9 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 16
MalSleek is on a distinguished road
Default

ah ok that makes more sense-thanks...still getting same error for the program build. I changed the scanf so it's looking for %s instead of %@. There must be something wrong with the lookup method still since it's not finding entries.

Mal

Last edited by MalSleek; 04-22-2009 at 10:15 PM.
MalSleek is offline   Reply With Quote
Old 04-22-2009, 10:47 PM   #10 (permalink)
Pro. Game Developer
iPhone Dev SDK Supporter
 
Join Date: Feb 2009
Location: żLa Islas Hermosas?
Posts: 2,176
Kalimba is on a distinguished road
Default

I don't think you can scanf() into an NSString, and even if you can I think your code would be scanning it into a nil instance. Try scanning the user's input into a char array, then build an NSString from that if you need to. Something like this should do the trick:
Code:
    char str[256]; // accepts a string up to 255 bytes long
    scanf( "%s", str ); // get the user's input into 'str'
BTW, have you tried debugging this or are you just running it to see whether it crashes or not? I think that if you were to step through your code in the debugger, you'd quickly see what's working and what's causing problems.
Kalimba is offline   Reply With Quote
Old 04-22-2009, 10:57 PM   #11 (permalink)
Former NeXTStep Developer
 
Join Date: Mar 2009
Posts: 997
FlyingDiver will become famous soon enough
Default

I don't think you're actually passing in a valid NSString. Since you're using scanf, you're getting a cstring. You need to then create an NSString from that to pass into the lookup method. Try:

Code:
char name[100];
NSString *nombre;
	
printf("What's the info you'd like to search for?");
scanf("%s", &name);

nombre = [NSString stringWithCString: name encoding: NSASCIIStringEncoding];

[myBook lookup: nombre];
And use some NSLog statements to verify what you're getting at each stage.

joe
FlyingDiver is offline   Reply With Quote
Old 04-22-2009, 11:19 PM   #12 (permalink)
New Member
 
Join Date: Mar 2009
Posts: 16
MalSleek is on a distinguished road
Default

Code:
char name[100];
	NSString *nombre;
	
	printf("What's the info you'd like to search for?");
	scanf("%s", &name);
	
	nombre = [NSString stringWithCString: name encoding: NSASCIIStringEncoding];
	
	myCard = [myBook lookup: nombre];
	
	if (myCard != nil)
		[myCard print];
	else
		printf("Not found!");
Okay took your word and it works! So it looks like the problem was that I couldn't pass the scanf without the right encoding.. Thanks very much for your help.

Kalimba I haven't tried just a debug, I've always done build and run and looked for errors - thank for the advice. I just started with this a few weeks ago so there are probably quite a few obvious things I'm overlooking

Thanks again -

Mal
MalSleek is offline   Reply With Quote
Old 01-29-2011, 07:46 AM   #13 (permalink)
Registered Member
 
Join Date: Jan 2011
Posts: 2
parag.deshpande is on a distinguished road
Thumbs up You should try following code to scan NSString object

#import<Foundation/Foundation.h>

int main(int argc, const char * argv[])
{

NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
char word[50];
scanf("%s",&word);

NSString* word2 =[NSString stringWithCString:word encoding: NSASCIIStringEncoding];



NSLog(@"%@",word2);
[pool release];
return 0;
}
parag.deshpande is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 455
16 members and 439 guests
Domele, Duncan C, Feldspar, karatebasker, MacBook MH, Objective Zero, patapple, Paul Slocum, peterwilli, pipposanta, PixelInteractive, Punkjumper, rubyeim54, SLIC, taylor202, Today's Posts
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,694
Threads: 94,137
Posts: 402,950
Top Poster: BrianSlick (7,990)
Welcome to our newest member, peterwilli
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 01:02 PM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0