Objective C - Method Definition not in #implementation context - objective-c

My Code:
#import <Foundation/Foundation.h>
-(NSString *) Fibonacci:(int) number{
//Fibonacci Calculations
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSLog(#"Fibonacci Output: %#", Fibonacci(5));
[pool drain];
return 0;
}
I am very new to Objective-C world and hence am not able to get the above working.
Facing the following errors:
Error(s):
source_file.m:5:1: error: method definition not in #implementation context
-(NSString *) lastdigitsFibonacci:(int) number{
^
source_file.m:6: confused by earlier errors, bailing out
Any help on the above would be deeply appreciated. Thanks

As #Larme said, Fibonacci(5) seems to be like a function. -(NSString *) Fibonacci:(int) number seems to be like a method.
So to call Fibonacci(5), you should rewrite -(NSString *) Fibonacci:(int) number as a func.
NSString* Fibonacci(int number) {
int t1 = 0;
int t2 = number > 1 ? 1 : 0;
int tmp;
for (int i = 3; i <= number; i++) {
tmp = t2;
t2 += t1;
t1 = tmp;
}
return [NSString stringWithFormat:#"%lu", t2];
}
int main(int argc, char* argv[]) {
#autoreleasepool {
NSLog(#"%#", Fibonacci(999));
}
}

#import <Foundation/Foundation.h>
NSString* Fibonacci(int number) ;
int main(int argc, const char * argv[]) {
#autoreleasepool {
// insert code here...
NSLog(#"Fibonacci Output: %#", Fibonacci(5));
}
return 0;
}
NSString* Fibonacci(int number)
{
//Fibonacci Calculations and return
}

Related

Invalid memory reference (SIGSEGV) and incomplete implementation of class error

I am writing a small recursive function to calculate the sum of integers from an array. However, I am getting errors and warnings. Anybody help me to solve these issues?
#import <Foundation/Foundation.h>
#interface SumIntegers:NSObject
{
NSInteger result;
}
-(NSInteger)calcutateSum:(NSInteger)value;
-(void) printSum;
#end
#implementation SumIntegers
-(NSInteger)calculateSum:(NSInteger)value
{
NSInteger sum = 0;
//sum = sum + [[self calculateSum:[array objectAtIndex:i]] integerValue];
sum = sum + [self calculateSum:value];
result = sum;
return result;
}
-(void) printSum
{
NSLog(#"Sum of integer list is %i",result);
}
#end
int main (int argc, const char * argv[])
{
NSInteger i;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *intArray = [NSMutableArray arrayWithObjects:[NSNumber numberWithInteger:1],[NSNumber numberWithInt:3],[NSNumber numberWithInt:5]
,[NSNumber numberWithInt:7],[NSNumber numberWithInt:9],nil];
SumIntegers *sumIntegers = [[SumIntegers alloc]init];
for (i = 0; i<[intArray count]; i++)
{
NSInteger hhh = [sumIntegers calculateSum:[[intArray objectAtIndex:i] integerValue]];
}
[sumIntegers printSum];
[pool drain];
return 0;
}
What I did is I created an interface SumIntegers and created a recursive function to calculate the sum of integers. However, somehow this function is not recognized and also getting warning "incomplete implementation of class #end" and memory error.
Warning(s):
source_file.m:31:1: warning: incomplete implementation of class ‘SumIntegers’
#end
^
source_file.m:31:1: warning: method definition for ‘-calcutateSum:’ not found
source_file.m: In function ‘main’:
source_file.m:44:19: warning: unused variable ‘hhh’ [-Wunused-variable]
NSInteger hhh = [sumIntegers calculateSum:[[intArray objectAtIndex:i] integerValue]];
^
Error(s):
Invalid memory reference (SIGSEGV)
Here is my answer to above problem. There is no need of return value or argument in the calculateSum method. Simply adding array value into the sum and then calling the calculateSum method again until num is less than array count.
#import <Foundation/Foundation.h>
#interface SumOfIntegers:NSObject
{
NSMutableArray *intArray;
NSInteger sum;
NSInteger num;
}
#property NSMutableArray *intArray;
#property NSInteger sum, num;
-(void) calculateSum;
#end
#implementation SumOfIntegers
#synthesize intArray, sum, num;
-(void) calculateSum{
if(num < [intArray count])
{
NSLog(#"number is.... %i", num);
sum = sum + [[intArray objectAtIndex:num++] integerValue];
[self calculateSum];
}
else
{
NSLog(#"Sum of integers is %i", sum);
}
}
#end
int main (int argc, const char *argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSMutableArray *array = [NSMutableArray arrayWithObjects:[NSNumber numberWithInteger:1],[NSNumber numberWithInt:3],[NSNumber numberWithInt:5]
,[NSNumber numberWithInt:7],[NSNumber numberWithInt:9],nil];
SumOfIntegers *sumOfIntegers = [[SumOfIntegers alloc]init];
sumOfIntegers.intArray = array;
sumOfIntegers.sum = 0;
sumOfIntegers.num = 0;
[sumOfIntegers calculateSum];
[pool drain];
return 0;
}
In modern ObjC:
int main(int argc, const char * argv[]) {
#autoreleasepool {
NSArray *nums = #[#(1), #(2), #(3)];
NSLog(#"%#", [nums valueForKeyPath:#"#sum.self"]);
}
return 0;
}

parse const char* argv[]

Code:-
#import <Foundation/Foundation.h>
int main(int argc, const char* argv[]){
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
char* charString = argv[1];
printf("%s", charString);
[pool drain];
return 0;
}
Problem:-
But the above line is printing null, how to get the array of integers;
argv[0] is the name of your program. If you want to read your parameters, start by reading argv[1]. Of course, you should also check that there are actually some parameters using argc > 1.
Or you could use [[NSProcessInfo processInfo] arguments]
int main(int argc, const char* argv[]){
#autoreleasepool {
for (NSInteger i = 0; i < argc; i++) {
NSString *stringArgument = [NSString stringWithFormat:#"%s", argv[i]];
NSLog(#"%#", stringArgument);
NSLog(#"Integer value: %i", [stringArgument intValue]);
}
}
return 0;
}
or
int main(int argc, const char* argv[]){
#autoreleasepool {
for (NSString *argument in [NSProcessInfo processInfo].arguments) {
NSLog(#"%#", argument);
NSLog(#"Integer value: %i", [argument intValue]);
}
}
return 0;
}
Arguments: 10 20
Output:
ObjcTest[65709:1964435] /Projects/ObjcTest/Build/Products/Debug/ObjcTest
ObjcTest[65709:1964435] Integer value: 0
ObjcTest[65709:1964435] 10
ObjcTest[65709:1964435] Integer value: 10
ObjcTest[65709:1964435] 20
ObjcTest[65709:1964435] Integer value: 20
Note the first argument cannot be converted to an integer therefore the printed value is 0.

string to int array in objective

Hi I trying to convert string to int array in objective C its running fine in xcode but give some error in editor http://ideone.com
I have input like = {1,2,3,4,5} and want to convert it into int array or NSARRAY in and print....
#import <Foundation/Foundation.h>
NSArray* sampleMethod(NSString*val){
NSString *stringWithoutbracketstart = [val stringByReplacingOccurrencesOfString:#"{" withString:#""];
NSString *stringWithoutbracketend = [stringWithoutbracketstart
stringByReplacingOccurrencesOfString:#"}" withString:#""];
NSLog(#"%#",stringWithoutbracketend);
NSArray *items=[[NSArray alloc]init];
items = [stringWithoutbracketend componentsSeparatedByString:#","];
//NSLog(#"%#",items);
return items;
}
int main(int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *value =#"{1,2,3}";
NSArray* ip1= sampleMethod(value);
NSLog(#"%#",ip1);
[pool drain];
return 0;
}
Why not make the input string valid JSON and then it can be arbitrarily extended with little coding effort (no effort at all with respect to parsing):
int main(int argc, const char **argv)
{
int retval = 0;
#autoreleasepool {
if (argc == 2) {
NSString *str = #(argv[1]);
NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
NSError *error = nil;
NSArray *array = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&error];
if ([array isKindOfClass:[NSArray class]]) {
// Done
} else if (!array) {
NSLog(#"Input data is invalid: %#", [error localizedDescription]);
retval = 2;
} else {
NSLog(#"Input data is invalid");
retval = 3;
}
} else {
NSLog(#"Provide a JSON-list");
retval = 1;
}
}
return retval;
}
This means you would need to supply the list in JSON format:
$ ./myprog '[ 1, 2, 3 ]'
(quotes are necessary)
I found the solution easily by using your advice....
#import <Foundation/Foundation.h>
NSArray*sampleMethod(NSString*val){
NSString *newStr = [val substringFromIndex:1];
NSString *newStr1 = [newStr substringToIndex:[newStr length]-1];
NSArray *yourWords = [newStr1 componentsSeparatedByString:#","];
return yourWords;
}
int main(int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *value =#"{1,2,3}";
NSArray* ip1= sampleMethod(value);
NSLog(#"%#",ip1);
[pool drain];
return 0;
}

Objective C Pointers

I am experiencing a very odd problem with pointers. As you could see from the below code, I am using a method that generates a random 4 by 4 character grid. It return a pointer to a two dimensional character array. The problem is that when i try to assign the returned pointer to another pointer and try to print the generated grid, I get just one strange symbol.
Header File
#import <Foundation/Foundation.h>
#interface GridGenerator : NSObject
{
}
-(char (*)[4]) generateGrid;
-(int (*)[2]) bbb;
-(void) print;
#end
Implementation File
#import "GridGenerator.h"
#implementation GridGenerator
-(char (*)[4])generateGrid{
char vowels[6] = {'A','E','I','O','U','Y'};
char consonants[20] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
char grid[4][4];
int vowelsLength = (sizeof vowels / sizeof vowels[0]);
int consLength = (sizeof consonants / sizeof consonants[0]);
int gridSize = (sizeof grid / sizeof grid[0]);
for(int i=0;i<gridSize;i++){
int vowelsInGridRow = 0;
int noOfVowels = (arc4random() % 2) + 1;
for(int j=0;j<gridSize;j++){
if(noOfVowels != vowelsInGridRow){
int vowIndex = arc4random() % vowelsLength;
char s = vowels[vowIndex];
grid[i][j] = s;
vowelsInGridRow++;
}
else{
int consIndex = arc4random() % consLength;
char s = consonants[consIndex];
grid[i][j] = s;
}
}
}
char (*sd)[4]= grid;
return sd;
}
-(void)print{
char (*grid)[4] = [self generateGrid];
NSString *s = #"\n";
for(int i=0;i<4;i++){
for(int j=0;j<4;j++){
s = [s stringByAppendingString:[NSString stringWithFormat:#"%c",grid[i][j]]];
}
s = [s stringByAppendingString:#"\n"];
}
NSLog(#"%#",s);
}
Main File(Test)
#import <Foundation/Foundation.h>
#import "Crossword.h"
#import "GridGenerator.h"
int main(int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GridGenerator *gen = [[GridGenerator alloc] init];
[gen print];
[pool release];
return 0;
}
When I run the code, you can see the result below. After the 'U' there is an inverted question mark(could not be pasted here).
2013-06-02 11:24:29.923 CrosswordTest[646:303]
U
Do you have an idea, what could causes this to happen? I am struggling already for several hours and I cannot find any explanation.
You are returning a reference to a temporary. Explosion (undefined behavior) should be expected.
Workaround. Create a structure:
typedef struct {char at[4][4];} t_grid;
Then populate and return the t_grid by value:
- (t_grid)generateGrid
{
char vowels[6] = {'A','E','I','O','U','Y'};
char consonants[20] = {'B','C','D','F','G','H','J','K','L','M','N','P','Q','R','S','T','V','W','X','Z'};
t_grid grid;
...
int gridSize = (sizeof grid.at / sizeof grid.at[0]);
...
grid.at[i][j] = s;
...
return grid;
}
- (void)print
{
t_grid grid = [self generateGrid];
...
Note that you should not use this approach for large arrays or variable length arrays. 4*4 octets is small.

md5 a string multiple times

md5 a string multiple times in Python:
def md5(i):
return hashlib.md5(i).hexdigest().upper()
def md5x3(src):
f = hashlib.md5(src).digest()
s = hashlib.md5(f).digest()
t = md5(s)
return t
how to implement above in C with OpenSSL on MacOS/iOS or in Objective-C without OpenSSL on MacOS/iOS ?
I'm try following, but its result is different from python's.
#import <Foundation/Foundation.h>
#import <CommonCrypto/CommonDigest.h>
#import <CommonCrypto/CommonCryptor.h>
static char* hextostr(const unsigned char* in , int len)
{
char* res = (char*)malloc(len * 2 + 1);
int i = 0;
memset(res , 0 , len * 2 + 1);
while(i < len)
{
sprintf(res + i * 2 , "%02x" , in[i]);
i ++;
};
// i = 0;
// int reslength;
// reslength=(int)strlen(res);
// while(i < reslength)
// {
// res[i] = toupper(res[i]);
// i ++;
// };
return res;
}
int main (int argc, const char * argv[])
{
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString * foo = #"abcdefghij";
NSData * buf1 = [foo dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result1[CC_MD5_DIGEST_LENGTH];
CC_MD5([buf1 bytes], (unsigned int)[buf1 length], result1);
NSData * buf2 = [[[NSString alloc] initWithFormat:#"%s", result1] dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result2[CC_MD5_DIGEST_LENGTH];
CC_MD5(result1, (unsigned int)strlen(result1), result2);
NSData * buf3 = [[[NSString alloc] initWithFormat:#"%s", result2] dataUsingEncoding:NSUTF8StringEncoding];
unsigned char result3[CC_MD5_DIGEST_LENGTH];
CC_MD5(result2, (unsigned int)strlen(result2), result3);
NSString * res = [[NSString alloc] initWithFormat:
#"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
result3[0], result3[1], result3[2], result3[3], result3[4], result3[5], result3[6], result3[7],
result3[8], result3[9], result3[10], result3[11], result3[12], result3[13], result3[14], result3[15]
];
NSLog(#"%s", hextostr(result1, CC_MD5_DIGEST_LENGTH));
NSLog(#"%s", hextostr(result2, CC_MD5_DIGEST_LENGTH));
NSLog(#"%s", hextostr(result3, CC_MD5_DIGEST_LENGTH));
[pool drain];
return 0;
}
Use a digest library, such as OpenSSL, which you probably have installed already. See http://www.openssl.org/docs/crypto/md5.html. Source code for MD5 is available at http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html.