Finding array objects from user input - objective-c

I'm trying to make it so the user input for my code corresponds with the objects in my array, but I have no idea how to do this.
Basically, the assignment says to right a program that will grade final exams, each question has one of four possible answers ( a,b,c,d) and the first answer in the array should correspond to the first question in the exam. The program should them prompt the user for their answers to the exam, and should be compared with the first correct answer in the array and if it matches, it'll give them points.
Problem is, I can't for the life of me figure out how to compare user input to my array to see if it's the right thing they put in.
Here's what I have so far!
I know I'm awful at it, but I'm trying my best. Any help will be extremely appreciated.
#import <Foundation/Foundation.h>
int main (int argc, char * argv[])
{
#autoreleasepool {
NSArray *correctAnswers= [NSArray arrayWithObjects: #"a", #"b ", #"c", #"d",nil];
int sum = 0;
int anwser;
{
NSLog(#"Please input test anwsers starting with 1:");
scanf("%i",&anwser);
}
if ([correctAnswers containsObject:#(anwser)]) {
sum = +10;
}else {
NSLog(#"Well that's not quite right...");
}
NSLog(#"The final score is:%d",sum);
}
return 0;
}

#"a" etc are NSString instances.
You would need to use NSString instance methods to compare them to the user input. You can also do fast enumeration with collections like NSArray
for (NSString* ans in correctAnswers)
{
if ([ans isEqualtoString:[NSString stringWithInt:anwser]]) sum+=10;
}
You could also use NSArray's filteredArrayUsingPredicate: to search the array.
But you can't use containsObject to compare strings... it just checks for a specific NSObject instance.
You also appear to be comparing an int to a char... but that's outside the scope of your question.

Related

Objective-C: Comparing user input with object's instance variable

I have been learning Objective-C for a while, and I decided to try and take on a little bigger project without any real "guidelines" as in the learning books but now I have got stuck.
What I'm trying to do is helping a friend digitalising a few documents he have, by creating a searchable commandline-tool for these documents.
I think I have gotten pretty far, I have created a custom class for documents with three variable; name of the author, number of the article and the path to the file on my computer (which I of course will change to the place he have the documents stored on his computer). I have then created two example documents with all the variables filled in. Since the documents have two properties, numbers and name of the author, the user may search for one of these properties. I therefore separated the input of the user to either be a string or a int (with help of a stack overflow post: How to determine if the first character of a NSString is a letter ) I also created an array with the 'author'-variable's of the different documents.
This is were I have hit a bump: I want to run through the array of the 'author' and if the author's name match with what the user have put in, it will open the document which is at the path given at 'UrlToDoc'. The problem is, the instance variable 'UrlToDoc' is not "connected" to the 'leadAuthor'-variable in some kind of way (as far as I can tell). My question is therefore, how do I, after I have found a match in in the array with what the user written, describe the 'UrlToDoc'-variable for that specific object? (If the user typed in jamesson, for instance, how do I describe the UrlToDoc variable with the value: /Users/pinkRobot435/Desktop/test1.pdf )
Also, if the user writes in a number, the else-statement on the bottom (which would do the same thing) should be used. I haven't written it yet though, but I guess the code for it would be pretty much the same, when describing the 'UrlToDoc'-variable.
Here is my code:
My custom class SMADoc:
SMADoc.h
#import <Foundation/Foundation.h>
#interface SMADoc : NSObject
//Two strings, and a pathway to the documnt, with the purpose of describing the document
#property (nonatomic) int number;
#property (nonatomic) NSString *authour;
#property (nonatomic) NSString *urlToDoc;
#end
SMADoc.m
#import "SMADoc.h"
#implementation SMADoc
#end
main.m
#import <Foundation/Foundation.h>
#import "SMADoc.h"
#include <readline/readline.h>
#include <stdlib.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
SMADoc *one = [[SMADoc alloc] init];
[one setnumber:123];
[one setauthour:#"jamesson"];
[one setUrlToDoc:#"/Users/pinkRobot435/Desktop/test1.pdf"];
SMADoc *two = [[SMADoc alloc] init];
[two setnumber:124];
[two setauthour:#"marc"];
[two setUrlToDoc:#"/Users/pinkRobot435/Desktop/test2.pdf"];
NSMutableArray *authours = [[NSMutableArray alloc] initWithObjects: [one authour], [two authour], nil];
NSLog(#"Enter what you want to search for: ");
const char *searchC = readline(NULL);
NSString *searchOrg = [NSString stringWithUTF8String:searchC];
NSString *search = [searchOrg lowercaseString];
NSRange first = [search rangeOfComposedCharacterSequenceAtIndex:0];
NSRange match = [search rangeOfCharacterFromSet:[NSCharacterSet letterCharacterSet] options:0 range:first];
if (match.location != NSNotFound) {
//The string starts with a letter and the array of authour names should be searched through
for (SMADoc *nSearch in authours) {
if ([search isEqualToString:nSearch]) {
**//Open the file that is represented by UrlToDoc for that specific object**
} else {
NSLog(#"The authour was not found, please try again");
}
}
} else {
//The string starts with a number and should be converted to an int and then the array of numbers (which I have not yet created) should be searched through
int number = atoi(searchC);
}
}
return 0;
}
Thanks in avance!
Instead of your authours array, create an array of SMADoc objects.
Then, in your loop, each object from the array will have an authour or number you can match. When the right one is found, you can just pick the urlToDoc out of the same object.
Currently, you're calling each object in the array a SMADoc * when you examine it, but that's wrong. You created an array of NSString * (and you're comparing it as a string correctly) but what you need there is a real SMADoc *.

Comparing a string in a NSMutableArray to a NSString

I'm very new to objective-c and this question may seem very simple so I am sorry if it is. I think I know how to get a user to input a string in C and comparing that to a string in an array by using strcmp. For instance (not sure if code is right as I'm not very good at c either)
char *arr[2];
arr[0] = "hello";
arr[1] = "goodbye";
char myString[10];
printf("enter greeting\n");
scanf("%s",myString);
if(strcmp(myString,arr[0]) == 0 )
{
printf("hello to you to");
}
if(strcmp(myString,arr[1]) == 0 )
{
printf("goodbye then");
}
But I'm trying to do the same thing with NSMutableArrays and NSStrings. So far it goes:
NSMutableArray *myStringArray = [[NSMutableArray alloc] init];
[myStringArray addObject:#"hello"];
[myStringArray addObject:#"goodbye"];
char greetingStr[40];
printf("enter greeting\n");
scanf("%s", greetingStr);
NSString *greeting = [NSString stringWithUTF8String:greetingStr];
//Some method to compare the strings
I was wondering what the code is the compare NSString with objects in NSMutableArrays. Sorry if it was badly explained but I am very new to programming and please keep any answers quite simple as I'm still very new to this. Thank you in advance.
"Some method to compare the strings" is:
isEqualToString:, if you're only interested in equality of strings;
compare:, if you also want to get information about their lexicographical ordering.

Objective-C: Comparing array of strings to user-entered string, then returning appropriate value?

This is a question about iOS programming with Objective C.
I have an NSMutableArray of strings "csvContent", that were parsed from a CSV file that contained a pseudo-database of questions, answers, and keywords. The contents of the CSV file were as follows:
ID#, "Here is the question I am asking?", "[question, key, words]", "This is the answer to your question."
There are about 2,000 of these questions and related keywords and answers, and I have successfully parsed them into the array, line by line so that each element contains everything in the example you see above.
My question is that if I want to have a user ask a question in a UITextField and then compare the UserQuestion and find the most similar question in my array of strings and then return its answer, what would be the best way to go about doing so? I've looked through documentation about Levenshtein distance and think that that would be a good option, but don't know how to exactly implement it and have it iterate through my entire CSVContent array. I'm not looking for exact code, but an ideal answer would contain some pseudocode or methodology on how to go about this.
To summarize:
Array of strings, CSVContent, of appearance: [id,"question",("question keywords"),"answer"].
I have a UITextField where I can parse a user's entered question into a string UserQuestion.
I want to use a fast comparison algorithm (Levenshtein?) to compare UserQuestion to the elements inside CSVContent and find the appropriate question and related answer, then return the answer.
When user hits the Search button, pass textField.text to this method:
- (int)matchingIDForString:(NSString *)userSuppliedText {
NSInteger bestLevDistanceSoFar = 9999999;
int indexOfMatch=-1;
// having to search the entire array each time is, of course, scary.
for ( int j=0; j<[myMutableArray count]; j++ ) {
NSString *candidateAnswer = [myMutableArray objectAtIndex:j];
// if candidateAnswer is a string, just use it. Else extract the member you want...
NSInteger *levDistance = [self myLevensteinDistanceMethod:candidateAnswer
forstring:userSuppliedText];
if ( levDistance < bestLevDistanceSoFar ) {
indexOfMatch = j;
bestLevDistanceSoFar = levDistance;
}
}
return indexOfMatch; // called should test for <0 meaning no match
}
You'll need to implement this method also:
- (NSInteger *)myLevensteinDistanceMethod:(NSString *)string1 forString:(NSString *)string2 {
// calculate the lev distance, and return it as an NSInteger *.
}

Using many integers in Objective-C

I'm new to programming, I have some basic python programming from college, I am familiar with some of the OOP basics and would like some help with managing large amounts of integers. I have 88 of them. 7 will be used for capturing user input and the other 81 will be used for a specific calculation. Instead of writing the following code:
int currentPlace;
int futurePlace;
int speed;
int distance;
int place1 = 1;
int place2 = 2;
int place3 = 3;
// etc...
int place81 = 81;
And then later coming back to the integers and asking user defined questions such as:
NSLog(#"What place is the runner in?");
scanf("%i", &currentPlace);
NSLog(#"What place does the runner finish in?");
scanf("%i", &futurePlace);
NSLog(#"What is the distance of the track?");
// doing some math
NSLog(#"The runner is running at "i" MPH.",speed);
I remember there being an easier way to use the integers but I keep thinking enums or typedefs.
I'd like for the user to pick a number and not have to run a huge if statement to get the work done to cut the size of the program as much as possible.
This is my first "on my own" application so any helpful pointers would be great.
Thanks.
I haven't understood why you need all these place's, but I also assume that an array would be easier to use here. You can use either NSArray or NSMutableArray. The difference between them is that an NSArray instance can't be changed after being created (you can't add/remove elements) unlike an NSMutableArray.
Using NSArray
NSArray *places = [NSArray arrayWithObjects:[NSNumber numberWithInt:1], [NSNumber numberWithInt:2],[NSNumber numberWithInt:3], ..., [NSNumber numberWithInt:81], nil];
nil at the end means the end of the contents of an array. [NSNumber numberWithInt:1] returns an int given as an argument (we can't straight give an int to the array, as an array expects an object as an argument.
You can access the contents of the array using:
[places objectAtIndex:(NSUInteger)];
Remeber that an array starts counting with 0, so if you want to get 5, you have to do this
[places objectAtIndex:4];
Using NSMutableArray
I suggest that you should use this option.
It's easier to use for here.
NSMutableArray *places = [NSMutableArray array];
for (int i = 1; i < 81; i++)
{
[places addObject:[NSNumber numberWithInt:i]];
}
Then you can access data the same way as in the NSArray:
[places objectAtIndex:0];
This will return 1. You can start the for-cycle with 0. After that the index of an array will correspond to the integer inside, so
[places objectAtIndex:5];
will actually return 5.
Are you thinking of a C array?
int myPlaces[81];
for (int i=0; i<81; i++) {
myPlaces[i] = 0;
}

Objective-C, Simple String input from Console?

I honestly did a) search using key words and b) read the 'questions with similar titles' before asking this.
Also I tried to make this question more concise, but I had a hard time doing that in this case. If you feel the question is too wordy, I get it. Just don't try to answer.
I'm trying to write very simple objective-C programs that mirror the basic assignments in my introductory java class. I worked through an objective-c book over the summer and now I want to do lots of practice problems in objective-c, at the same time as I do java practice problems. I'm avoiding the objective-c GUI environment and just want to focus on working with the language for awhile. I still have a lot to learn about how to figure things out.
The program I'm duplicating from my java homework, is a standard type. I ask the user for number input and string input via the console. I was able to get numeric input from the console using an example I found here using scan f. (I will put the couple code lines below). But I'm unsure on how to get console input and store it in a string (NSString). I'm trying to learn to use the apple documentation and found a reference to a scan type command, but I cannot figure out how to USE the command. The one that seems likely is
scanCharactersFromSet:(NSCharacterSet )scanSet intoString:(NSString *)name;
Here's what I understand and works
int age = 0;
NSLog (#"How old are y'all?");
scanf("%d", &age);
NSLog (#"\n Wow, you are %d !", age);
But I don't understand how to pickup an NSString called 'name'. I THINK I'm supposed to make my 'name'a pointer, because the class is NSString.
(BTW I did try using scanf to pickup the string, but the compiler doesn't like me trying to use scanf in conjunction with name. It says that I shouldn't be using 'scanf' because it's expecting a different kind of data. I'm not sure where I found the data type 'i'. I was looking through my text for different ideas. I'm guessing that scanf is related to 'scanfloat' which clearly deals with numeric data, so this is not a big surprise)
I realize that 'scanf' isn't the right command (and I don't really get why I can't even find scanf in the apple documentation - maybe it's C?)
I'm guessing that scanCharactersFromSet might be the right thing to use, but I just don't understand how you figure out what goes where in the command. I guess I tend to learn by example, and I haven't found an example. I'd like to figure out how to learn properly by reading the documentation. But I'm not there yet.
NSString* name ;
scanf("%i", &name);
//scanCharactersFromSet:(NSCharacterSet *)scanSet intoString:(NSString **)name;
...
My book is oriented towards moving me into a gui environment, so it doesn't deal with input.
Thank you for any pointers you can give me.
Laurel
I would recommend ramping up on C. Objective-c is a thin layer over C and that knowledge will pay for itself over and over.
There's multiple ways in C to read:
http://www.ehow.com/how_2086237_read-string-c.html
For example:
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
char str[50] = {0}; // init all to 0
printf("Enter you Last name: ");
scanf("%s", str); // read and format into the str buffer
printf("Your name is %s\n", str); // print buffer
// you can create an NS foundation NSString object from the str buffer
NSString *lastName = [NSString stringWithUTF8String:str];
// %# calls description o object - in NSString case, prints the string
NSLog(#"lastName=%#", lastName);
[pool drain];
return 0;
NOTE: the simple scanf is succeptible to buffer overruns. There's multiple approaches around this. see:
How to prevent scanf causing a buffer overflow in C?
Here is what Objective C looks like:
NSString *FNgetInput() {
#autoreleasepool {
return [[[NSString alloc] initWithData:[[NSFileHandle fileHandleWithStandardInput] availableData] encoding:NSUTF8StringEncoding] stringByTrimmingCharactersInSet:[NSCharacterSet newlineCharacterSet]];
}
}
The way to get data from the standard input (or any other file handle) in cocoa is to use the NSFileHandle class. Check the docs for +fileHandleWithStandardInput
Here's how to get user input using Objective-C in 2020:
main.m
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Hello, World!");
char str[50] = {0}; // init all to 0
printf("Enter you Last name: ");
scanf("%s", str); // read and format into the str buffer
printf("Your name is %s\n", str); // print buffer
// you can create an NS foundation NSString object from the str buffer
NSString *lastName = [NSString stringWithUTF8String:str];
// %# calls description o object - in NSString case, prints the string
NSLog(#"lastName=%#", lastName);
return 0;
}
return 0;
}
Compile and run:
$ clang -framework Foundation main.m -o app