Objective C - Accessing Normal C Array - iphone

I am making a game that assigns a label a question from a regular C array.
- (void)viewDidLoad
{
[super viewDidLoad];
for (int i = 0; i < 45; i++) {
basketball_numbers1[i] = (arc4random()%999)+100;
basketball_numbers2[i] = (arc4random()%999)+100;
for (int j = 0; j < 30; j++) {
int first = basketball_numbers1[i];
int second = basketball_numbers2[i];
basketball_questions[j] = [[NSString stringWithFormat: #"%d + %d", first, second] retain];
basketball_answers[j] = [[NSString stringWithFormat: #"%d", basketball_numbers1[i] + basketball_numbers2[i]] retain];
}
}
This code works and printed the questions and answers to the console no problem before I commented them out.
But when I'm running the emulator and type in the correct answer, the same questions stays on the label, even though the count (variable used to increase the index of the array) increases, which I confirmed via NSLog.
Some other notes: when I had manually put in values for the array, it worked no problem. Also I added in the 'retain' to the end of the array after doing some research, which actually eliminated some problems I was having before this, but I'm not sure if retain/release are used in regular C arrays or just NSArray.
Here is the code that reads in the textfield upon a button click.
- (IBAction)basketball_click:(id)sender {
basketball_input = self.basketball_textfield.text;
NSLog(#"INPUT: %#", self.basketball_textfield.text);
if ([self.basketball_textfield.text isEqualToString:(basketball_answers[count])]) {
NSLog(#"THEY ARE EQUAL");
isCorrect = TRUE;
self.basketball_textfield.text = #"";
}
...
if(isCorrect) {
NSLog(#"Retain Count: %d", [basketball_questions[count] retainCount]);
correct.text = #"CORRECT!";
basketball_right++;
count++;
NSLog(#"COUNT: %d", count);
question_label.text = basketball_questions[count];
NSLog(#"NEW QUESTION: %#", basketball_questions[count]);
}

for (int i = 0; i < 45; i++) {
first = (arc4random()%999)+100;
last = (arc4random()%999)+100;
basketball_questions[i] = [[NSString stringWithFormat: #"%d + %d", first, second] retain];
basketball_answers[i] = [[NSString stringWithFormat: #"%d", first+last] retain];
}

Related

hex a to binary

i am trying to convert my hex value to binary value , but i am facing little problem .
as i am new trying to learn my faults .
my code :
NSMutableString *str;
NSString *dd = #"192:168:1:2:0B:2:D:00";
NSCharacterSet *donotwant1 = [NSCharacterSet characterSetWithCharactersInString:#":""];
dd =[[dd componentsSeparatedByCharactersInSet:donotwant1] componentsJoinedByString:#" "];
NSMutableArray *array = [[dd componentsSeparatedByString:#" "] mutableCopy];
[array removeObjectAtIndex:0];
//NSLog(#"%#",array);
for (int j=0; j<[array count]; j++) {
NSScanner *scan = [NSScanner scannerWithString:[array objectAtIndex:j]];
unsigned int i=0;
if ([scan scanHexInt:&i]) {
// NSLog(#"numbner is %ustr", i);
}
NSInteger theNumber = i;
str = [NSMutableString string];
for(NSInteger numberCopy = theNumber; numberCopy > 0; numberCopy >>= 1) {
// Prepend "0" or "1", depending on the bit
[str insertString:((numberCopy & 1) ? #"1" : #"0") atIndex:0];
[array removeObjectAtIndex:j];
[array insertObject:str atIndex:j];
}
}
NSLog(#"Binary version: %#", array);
I'm getting
1,1100,11001111,1111,1111,11101111.....
in my code 0 values are eliminated . i want 8bits like(00000001,00001100.....) can any one tell me the reason
When the most significant bit is reached, your algorithm stops the conversion. Why not force the loop to always execute 8 times?
for (int numberCopy = theNumber, int i = 0; i < 8; numberCopy >>= 1, i++) {
// loop body here
}
By the way, here's a cleaner/shorter/simpler approach that doesn't involve highly superfluous copying and uses characters instead of string objects for hyper efficiency (just kidding, I'm all against micro-optimizations, but I feel like inserting an NSString before another one is unnecessary, especially if the number of bits is known and constant). This also assumes UTF-8 and exploits the fact that hexadecimal and binary representation have a very nice relationship, 16 being the 4th power of 2:
NSString *dd = #"01:0C:CF:0F:EF:AF:BD:00";
NSArray *bytes = [dd componentsSeparatedByString:#":"];
NSMutableArray *binaries = [NSMutableArray array];
NSString *lookup[256];
lookup['0'] = #"0000";
lookup['1'] = #"0001";
lookup['2'] = #"0010";
lookup['3'] = #"0011";
lookup['4'] = #"0100";
lookup['5'] = #"0101";
lookup['6'] = #"0110";
lookup['7'] = #"0111";
lookup['8'] = #"1000";
lookup['9'] = #"1001";
lookup['A'] = #"1010";
lookup['B'] = #"1011";
lookup['C'] = #"1100";
lookup['D'] = #"1101";
lookup['E'] = #"1110";
lookup['F'] = #"1111";
for (NSString *s in bytes) {
unichar n1 = [s characterAtIndex:0];
unichar n0 = [s characterAtIndex:1];
[binaries addObject:[lookup[n1] stringByAppendingString:lookup[n0]]];
}
NSLog(#"%#", binaries);

Giving labels names with array

Okay, so i'm trying to give 7 different labels names using an array and a for loop.
Code:
id huller[] = {hul18.text, hul17.text, hul16.text, hul15.text, hul14.text, hul13.text, hul12.text, hul11.text, hul10.text, hul9.text, hul8.text, hul7.text, hul6.text, hul5.text, hul4.text, hul3.text, hul2.text, hul1.text};
for (int i = 0; 7 > i; i++) {
huller[i] = [NSString stringWithFormat:#"%i", x + 1];
NSLog(#"%#", huller[i]);
}
The name change in the NSLog, but they do not change in the simulator. What is wrong?
Assuming hul18, hul17, etc. are all UILabel objects, then do this:
NSArray *labels = [ hul18, hul17, hul16, hul15, hul14, hul13, hul12, hul11, hul10, hul9, hul8, hul7, hul6, hul5, hul4, hul3, hul2, hul1 ];
// Change the text of every label in the array
for (int i = 0; i < labels.count; i++) {
UILabel *label = labels[i];
label.text = [NSString stringWithFormat:#"%i", x + 1]; // Do you really want 'x' here or 'i'?
NSLog(#"%#", label.text);
}
If you want the text to change too, then you have to set the text manually.
NSArray *labels = //Array of labels;
for (int i = 0; 7 > i; i++) {
huller[i] = [NSString stringWithFormat:#"%i", x + 1];
labels[i].text = huller[i];
NSLog(#"%#", huller[i]);
}

How to sort an array with alphanumeric values?

I have an array which contains strings like frame_10#3x.png , frame_5#3x.png,frame_19#3x.png etc.
So I want to sort this array according to the number after the underscore i.e. the correct sequence will be frame_5#3x.png,frame_10#3x.png,frame_19#3x.png.
I tried to use the following method but no result:
NSInteger firstNumSort(id str1, id str2, void *context) {
int num1 = [str1 integerValue];
int num2 = [str2 integerValue];
if (num1 < num2)
return NSOrderedAscending;
else if (num1 > num2)
return NSOrderedDescending;
return NSOrderedSame;
}
Please suggest how to do this sorting for array.
NSArray *sry_img = [[NSArray alloc] initWithObjects:#"frame_18#3x.png",#"frame_17#3x.png",#"frame_1222#3x.png",#"frame_10#3x.png",#"frame_3#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",#"frame_1#3x.png",#"frame_4#3x.png",#"frame_4#3x.png",nil];
NSArray *sortedStrings = [sry_img sortedArrayUsingSelector:#selector(localizedStandardCompare:)];
NSLog(#"%#",sortedStrings);
Enjy .......
But
localizedStandardCompare:, added in 10.6, should be used whenever file names or other strings are presented in lists and tables where Finder-like sorting is appropriate. The exact behavior of this method may be tweaked in future releases, and will be different under different localizations, so clients should not depend on the exact sorting order of the strings.
you want to do something like:
NSArray *components1 = [str1 componentsSeparatedByString:#"_"];
NSArray *components2 = [str2 componentsSeparatedByString:#"_"];
NSString *number1String = [components1 objectAtIndex:([components1 count] - 1])];
NSString *number2String = [components2 objectAtIndex:([components2 count] - 1])];
return [number1String compare:number2String];
I am not sure if my solution is the best possible approach but it can solve your problem for the time being :) .
1) First I have written a function to get the numbers before # character in your string and then I implemented simple SELECTION SORT algo to sort the array using this functions.
- (NSString*)getSubStringForString:(NSString*)value {
// First we will cut the frame_ string
NSMutableString *trimmedString = [NSMutableString stringWithString:[value substringWithRange:NSMakeRange(6, [value length]-6)]];
// New String to contain the numbers
NSMutableString *newString = [[NSMutableString alloc] init];
for (int i = 0; i < [trimmedString length] ; i++) {
NSString *singleChar = [trimmedString substringWithRange:NSMakeRange(i, 1)];
if (![singleChar isEqualToString:#"#"]) {
[newString appendString:singleChar];
} else {
break;
}
}
return newString;
}
This is the selection Implementation of the algo for sorting. The main logic is in the for loop. You can copy the code in viewDidLoad method to test.
NSMutableArray *array = [[NSMutableArray alloc] initWithObjects:#"frame_10#3x.png",#"frame_5#3x.png",
#"frame_3#3x.png", #"frame_19#3x.png",
nil];
NSLog(#"Values before Sort: %#", array);
int iPos;
int iMin;
for (iPos = 0; iPos < [array count]; iPos++)
{
iMin = iPos;
for (int i = iPos+1; i < [array count]; i++)
{
if ([[self getSubStringForString:[array objectAtIndex:i]] intValue] >
[[self getSubStringForString:[array objectAtIndex:iMin]] intValue]) {
iMin = i;
}
}
if ( iMin != iPos )
{
NSString *tempValue = [array objectAtIndex:iPos];
[array replaceObjectAtIndex:iPos withObject:[array objectAtIndex:iMin]];
[array replaceObjectAtIndex:iMin withObject:tempValue];
}
}
NSLog(#"Sorted Values: %#", array);
I hope that it can atleast keep you going. :)
You can try this-
NSString *str1 = [[[[str1 componentsSeparatedByString:#"frame_"] objectAtIndex:1] componentsSeparatedByString:#"#3x.png"] objectAtIndex:0];
int num1 = [str1 integerValue];

NSString range of string at occurrence

i'm trying to build a function that will tell me the range of a string at an occurrence.
For example if I had the string "hello, hello, hello", I want to know the range of hello at it's, lets say, third occurrence.
I've tried building this simple function, but it doesn't work.
Note - the top functions were constructed at an earlier date and work fine.
Any help appreciated.
- (NSString *)stringByTrimmingString:(NSString *)stringToTrim toChar:(NSUInteger)toCharacterIndex {
if (toCharacterIndex > [stringToTrim length]) return #"";
NSString *devString = [[[NSString alloc] init] autorelease];
for (int i = 0; i <= toCharacterIndex; i++) {
devString = [NSString stringWithFormat:#"%#%#", devString, [NSString stringWithFormat:#"%c", [stringToTrim characterAtIndex:(i-1)]]];
}
return devString;
[devString release];
}
- (NSString *)stringByTrimmingString:(NSString *)stringToTrim fromChar:(NSUInteger)fromCharacterIndex {
if (fromCharacterIndex > [stringToTrim length]) return #"";
NSString *devString = [[[NSString alloc] init] autorelease];
for (int i = (fromCharacterIndex+1); i <= [stringToTrim length]; i++) {
devString = [NSString stringWithFormat:#"%#%#", devString, [NSString stringWithFormat:#"%c", [stringToTrim characterAtIndex:(i-1)]]];
}
return devString;
[devString release];
}
- (NSRange)rangeOfString:(NSString *)substring inString:(NSString *)string atOccurence:(int)occurence {
NSString *trimmedString = [inString copy]; //We start with the whole string.
NSUInteger len, loc, oldLength;
len = 0;
loc = 0;
NSRange tempRange = [string rangeOfString:substring];
len = tempRange.length;
loc = tempRange.location;
for (int i = 0; i != occurence; i++) {
NSUInteger endOfWord = len+loc;
trimmedString = [self stringByTrimmingString:trimmedString fromChar:endOfWord];
oldLength += [[self stringByTrimmingString:trimmedString toChar:endOfWord] length];
NSRange tmp = [trimmedString rangeOfString:substring];
len = tmp.length;
loc = tmp.location + oldLength;
}
NSRange returnRange = NSMakeRange(loc, len);
return returnRange;
}
Instead of trimming the string a bunch of times (slow), just use rangeOfString:options:range:, which searches only within the range passed as its third argument. See Apple's documentation.
So try:
- (NSRange)rangeOfString:(NSString *)substring
inString:(NSString *)string
atOccurence:(int)occurence
{
int currentOccurence = 0;
NSRange rangeToSearchWithin = NSMakeRange(0, string.length);
while (YES)
{
currentOccurence++;
NSRange searchResult = [string rangeOfString: substring
options: NULL
range: rangeToSearchWithin];
if (searchResult.location == NSNotFound)
{
return searchResult;
}
if (currentOccurence == occurence)
{
return searchResult;
}
int newLocationToStartAt = searchResult.location + searchResult.length;
rangeToSearchWithin = NSMakeRange(newLocationToStartAt, string.length - newLocationToStartAt);
}
}
You need to rework the whole code. While it may seem to work, it's poor coding and plain wrong, like permanently reassigning the same variable, initializing but reassigning one line later, releasing after returning (which will never work).
For your question: Just use rangeOfString:options:range:, and do this the appropriate number of times while just incrementing the starting point.

Why doesn't this for loop execute?

I have a picker view controller to select a chemical source and possibly a concentration. If the source doesn't have concentrations, it just presents a single picker. It gets populated by an NSDictionary with source type names as keys and a custom model object I made called Chemical that has four properties, two NSString, one float and one BOOL.
When I trigger this with dictionary that has 2 components, I want to extract the four values from the Chemical that is represented. Note that I populate the picker with values from the first two properties, but not the float or BOOL. I run through the array for the key that's selected in the first component and check the string from the second component against the chemConcentration property from each of the Chemicals in the key/value array. When the chemConcentration matches, I know I have the right Chemical and I can get its properties to send back.
Whew!
The problem is that even though I know I get to the for loop, it seems to get skipped. The NSLog right before it prints, but the one inside doesn't. sourceConstant and sourceIsLiquid stay 0.0 and NO
- (IBAction)selectedSourceButton {
NSLog(#"selectedSourceButton pressed");
NSInteger sourceRow = [picker selectedRowInComponent:kSourceComponent];
NSString *selectedSource = [self.sources objectAtIndex:sourceRow];
NSArray *selectedChemicalGroup = [dictionaryOfSources objectForKey:selectedSource];
NSInteger concentrationRow = [picker selectedRowInComponent:kConcentrationComponent];
NSString *selectedConcentration = [[NSString alloc] init];
float selectedConstant = 0.0;
BOOL selectedIsLiquid = NO;
if (numberOfComponents == 2) {
NSLog(#"numberOfComponents = 2 if/then chosen"); // <-- This prints.
selectedConcentration = [self.concentrations objectAtIndex:concentrationRow];
NSLog(#"begin selectedConcentration for loop. Number of loops = %d", [selectedChemicalGroup count]); // <-- And so does this.
for (int i; i<[selectedChemicalGroup count]; i++) { // <-- But this doesn't seem to fire!
NSLog(#"selectedConcentration = %#, from selectedChemicalGroup = %#", selectedConcentration, [[selectedChemicalGroup objectAtIndex:i] chemConcentration]); // <-- Because this doesn't print.
if ([selectedConcentration isEqualToString:[[selectedChemicalGroup objectAtIndex:i] chemConcentration]]) {
selectedConstant = [[selectedChemicalGroup objectAtIndex:i] chemConstant];
selectedIsLiquid = [[selectedChemicalGroup objectAtIndex:i] chemIsLiquid];
}
}
}
else {
selectedConcentration = #"";
selectedConstant = [[selectedChemicalGroup objectAtIndex:0] chemConstant];
selectedIsLiquid = [[selectedChemicalGroup objectAtIndex:0] chemIsLiquid];
}
NSLog(#"selectedSourceButton source to return = %#, concentration = %#, sourceConstant = %1.7f, isLiquid = %d", selectedSource, selectedConcentration, selectedConstant, selectedIsLiquid);
if ([self.delegate respondsToSelector:#selector (sourcePickerViewController:didSelectSource:andConcentration:andConstant:andIsLiquid:)]) {
[self.delegate sourcePickerViewController:self didSelectSource:selectedSource andConcentration:selectedConcentration andConstant:selectedConstant andIsLiquid:selectedIsLiquid];
}
}
You need to initialize your variable i: for (int i = 0; ...
But there's a better way to do this, using "fast enumeration":
for (MyChemicalGroupClass *group in selectedChemicalGroup) {
if ([selectedConcentration isEqualToString:[group chemConcentration]]) {
...
}
}
Initialize loop count i
for (int i = 0; i<[selectedChemicalGroup count]; i++)
Do the following and you will understand why:
int i;
NSLog(#"%d", i);