string to int array in objective - objective-c

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;
}

Related

how to convert const char * argv[] in NSArray in Objective C

I just want to convert the const char * argv[] in main method to NSArray or NSMutableArray. But I am really stuck and couldn't find any solution.
Any help will be appreciated.
You have a C-array of char * (C strings). You need to convert each C string into an NSString. Then you can add each NSString to your NSMutableArray.
int main(int argc, char *argv[]) {
NSMutableArray *results = [NSMutableArray array];
for (int i = 0; i < argc; i++) {
NSString *str = [[NSString alloc] initWithCString:argv[i] encoding:NSUTF8StringEncoding];
[results addObject:str];
}
}

hackerrank.com find-hackerrank solution on Obj-C

I'm trying to solve https://www.hackerrank.com/challenges/find-hackerrank on Obj-C, and get ok output via xCode, but not via hackerrank's "Run Code" button.
xCode output:
hackerrank output:
So it is at leat strange to see different outputs.
my code:
#import <Foundation/Foundation.h>
int main()
{
NSFileHandle *input;
NSData *inputData;
NSString *match = #"hackerrank";
int amount;
NSString *str;
input = [NSFileHandle fileHandleWithStandardInput];
inputData = [input availableData];
amount = [[[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding] intValue];
for (int j = 0; j < amount; j++)
{
inputData = [input availableData];
str = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding];
str = [str stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSArray *redexArr = #[match,
[NSString stringWithFormat:#"^%#.+", match],
[NSString stringWithFormat:#".+%#$", match]
];
for (int i = 2; i>=-1; i--)
{
if (i <= -1)
{
printf("-1\n");
} else
{
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", redexArr[i]];
if ([pred evaluateWithObject:str])
{
printf("%d\n", i);
break;
}
}
}
}
return 0;
}
Any ideas?
The difference between the run in Xcode and on HackerRank is that when you run locally, the call to
[input availableData];
stops when your program have read the next line from console. This lets you call availableData multiple times, each time getting the next line.
On HackerRank, though the very first call of availableData gets the entire file, leaving nothing to the rest of your program to consume.
You can fix this problem by reading the file line-by-line, or reading the entire content, and splitting it on end-of-line markers.
Here is your fixed submission that passes all tests on HackerRank:
#import <Foundation/Foundation.h>
int main()
{
NSFileHandle *input;
NSString *match = #"hackerrank";
int amount;
input = [NSFileHandle fileHandleWithStandardInput];
NSArray *inputData = [[[NSString alloc] initWithData:[input availableData] encoding:NSUTF8StringEncoding] componentsSeparatedByString: #"\n"];
amount = [inputData[0] intValue];
for (int j = 1; j <= amount; j++)
{
NSString *str = inputData[j];
NSArray *redexArr = #[match,
[NSString stringWithFormat:#"^%#.+", match],
[NSString stringWithFormat:#".+%#$", match]
];
for (int i = 2; i>=-1; i--)
{
if (i <= -1)
{
printf("-1\n");
} else
{
NSPredicate *pred = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", redexArr[i]];
if ([pred evaluateWithObject:str])
{
printf("%d\n", i);
break;
}
}
}
}
return 0;
}

Simple Objective C program - It can't be this complex

I'm in the process of learning Objective C and decided to create a simple command line program. The idea is that is asks you for your name and then displays it backwards, capitalizing the first letter of each word. I got it done but the solution seems overly complex. I can't help but feel there is a better way.
char word [256];
printf("What is your name: ");
scanf("%[^\n]s",word);
// Convert the char array to NSString
NSString * inputString = [[NSString alloc] initWithCString: word encoding: NSUTF8StringEncoding];
//This will be our output string
//NSString *nameReversed = [[NSString alloc] init]; //alloc, init are needed to create an instance of this object
NSString *nameReversed = #"";
// Make inputString all lower case
inputString = [inputString lowercaseString];
// Get length of inputString and type cast it as an int and decrement by one
int length = (int)([inputString length])-1;
BOOL foundSpace = NO;
for (int i = 0; i<=(length); i++) {
// Setup the range
NSRange range = NSMakeRange(length-i,1);
// Get the a char from the input string
NSString *inputChar = [inputString substringWithRange:range];
// If this is the first char then make it upper case
if (i==0) {
inputChar = [inputChar capitalizedString];
}
// See if the last char was a space and if so make this char upper case
if (foundSpace){
foundSpace = NO; // Reset foundSpace
// Set this char to upper case
inputChar = [inputChar capitalizedString];
}
// See if this char is a space. If so, we'll need to convert the next char to upper case
if ([inputChar isEqual: #" "]) {
foundSpace = YES;
}
// Add the char to nameReversed
nameReversed = [nameReversed stringByAppendingString:inputChar];
}
printf("%s \n", [nameReversed UTF8String]);
Any insight would be appreciated!
Your program doesn't handle composed character sequences properly.
Also, capitalizedString will capitalize the first letter of each word in the string. So you can just call it once.
static NSString *reversedString(NSString *string) {
NSMutableString *reversed = [NSMutableString stringWithCapacity:string.length];
[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
options:NSStringEnumerationReverse
| NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[reversed appendString:substring];
}];
return reversed;
}
int main(int argc, const char * argv[])
{
#autoreleasepool {
NSData *inputData = [[NSFileHandle fileHandleWithStandardInput] readDataToEndOfFile];
NSString *original = [[NSString alloc] initWithData:inputData encoding:NSUTF8StringEncoding];
NSString *reversed = reversedString(original);
NSString *reversedAndCapitalized = [reversed capitalizedString];
printf("%s\n", reversedAndCapitalized.UTF8String);
}
return 0;
}
In a real app I'd probably add a category on NSString defining a reversedString method, instead of making it a free function.
If you assume the input is in ascii encoding.
char word [256];
printf("What is your name: ");
scanf("%[^\n]s", word);
// reverse
for (NSInteger i=0,j=strlen(word)-1; i<j; i++,j--) {
char tmp = word[i];
word[i] = word[j];
word[j] = tmp;
}
NSString *str0 = [NSString stringWithCString:word encoding:NSASCIIStringEncoding];
NSLog(#"%#", [str0 capitalizedString]);

Substring to nth character

I need to substring to the 2nd comma in an NSString.
Input:
NSString *input = #"title, price, Camry, $19798, active";
Desired Output:
NSString *output = #"title, price";
Thanks!
UPDATE:
I have the following but the problem is it needs to skip the last comma:
NSString *output = [input rangeOfString:#"," options:NSBackwardsSearch];
Try this:
- (NSString *)substringOfString:(NSString *)base untilNthOccurrence:(NSInteger)n ofString:(NSString *)delim
{
NSScanner *scanner = [NSScanner scannerWithString:base];
NSInteger i;
for (i = 0; i < n; i++)
{
[scanner scanUpToString:delim intoString:NULL];
[scanner scanString:delim intoString:NULL];
}
return [base substringToIndex:scanner.scanLocation - delim.length];
}
this code should do what you need:
NSString *input = #"title, price, Camry, $19798, active";
NSArray *array = [input componentsSeparatedByString:#","];
NSArray *subArray = [array subarrayWithRange:NSMakeRange(0, 2)];
NSString *output = [subArray componentsJoinedByString:#","];
NSLog(output);
You could split -> splice -> join that string like this in objc:
NSString *input = #"title, price, Camry, $19798, active";
// split by ", "
NSArray *elements = [input componentsSeparatedByString: #", "];
// grab the subarray
NSArray *subelements = [elements subarrayWithRange: NSMakeRange(0, 2)];
// concat by ", " again
NSString *output = [subelements componentsJoinedByString:#", "];
You can try something like this:
NSArray *items = [list componentsSeparatedByString:#", "];
NSString result = #"";
result = [result stringByAppendingString:[items objectAtIndex:0]];
result = [result stringByAppendingString:#", "];
result = [result stringByAppendingString:[items objectAtIndex:1]];
You have to check you have at least two items if you want avoid an exception.
There's really nothing wrong with simply writing the code to do what you want. Eg:
int commaCount = 0;
int i;
for (i = 0; i < input.count; i++) {
if ([input characterAtIndex:i] == (unichar) ',') {
commaCount++;
if (commaCount == 2) break;
}
}
NSString output = nil;
if (commaCount == 2) {
output = [input substringToIndex:i];
}
You could create an NSString category to handle finding nth occurrences of any string. This is example is for ARC.
//NSString+MyExtension.h
#interface NSString(MyExtension)
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string;
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string
options:(NSStringCompareOptions)options;
#end
#implementation NSString(MyExtension)
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string
{
return [self substringToNthOccurrence:nth ofString:string options:0];
}
-(NSString*)substringToNthOccurrence:(NSUInteger)nth
ofString:(NSString*)string
options:(NSStringCompareOptions)options
{
NSUInteger location = 0,
strlength = [string length],
mylength = [self length];
NSRange range = NSMakeRange(location, mylength);
while(nth--)
{
location = [self rangeOfString:string
options:options
range:range].location;
if(location == NSNotFound || (location + strlength) > mylength)
{
return [self copy]; //nth occurrence not found
}
if(nth == 0) strlength = 0; //This prevents the last occurence from being included
range = NSMakeRange(location + strlength, mylength - strlength - location);
}
return [self substringToIndex:location];
}
#end
//main.m
#import "NSString+MyExtension.h"
int main(int argc, char *argv[])
{
#autoreleasepool {
NSString *output = [#"title, price, Camry, $19798, active" substringToNthOccurrence:2 ofString:#","];
NSLog(#"%#", output);
}
}
*I'll leave it as an exercise for someone to implement the mutable versions.

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.