Objective-C Calculating string value - objective-c

This is my main:
int x=0;
NSString *new=[[NSString alloc]initWithString:#"9+4"];
x=[new intValue];
NSLog(#"hi %i",x);
This results in 9.. .since giving the intValue of a string will read only numbers and stops when the character is not a digit.
So how can i print the result of my string and get a 13 instead??

Actually, NSExpression was made just for this:
NSExpression *expression = [NSExpression expressionWithFormat:#"9+4"];
// result is a NSNumber
id result = [expression expressionValueWithObject:nil context:nil];
NSLog(#"%#", result);
NSExpression is very powerful, I suggest you read up on it. You can use variables by passing in objects through the format string.

Change this line
NSString *new=[[NSString alloc]initWithString:#"9+4"];
to
NSString *new=[NSString stringWithFormat:#"%f",9+4];

You will have to manually parse it. You could write a subclass of NSString that overrides the intValue method, and parses it to find arithmetic symbols and perform the math, but thats as close to automatic as you're gonna get I'm afraid

You will need to parse and evaluate it yourself, as seemingly simple calculations like this are beyond the scope of the basic string parsing Apple provides you. It might seem to be a no-brainer if you're used to interpreted languages like Ruby, Perl and the like. But for a compiled language support for runtime evaluation of expressions are uncommon (there are languages that do support them, but Objective-C is not one of them).

When attempting to parse an expression in a string you will want to use Reverse Polish Notation. Here is the first example I cam across in a google search for Objective-C.

Related

Objective-C equivalent of Swift "\(variable)"

The question title says it all, really. In swift you use "\()" for string interpolation of a variable. How does one do it with Objective-C?
There is no direct equivalent. The closest you will get is using a string format.
NSString *text = #"Tomiris";
NSString *someString = [NSString stringWithFormat:#"My name is %#", text];
Swift supports this as well:
let text = "Tomiris"
let someString = String(format: "My name is %#", text)
Of course when you use a format string like this (in either language), the biggest issue is that you need to use the correct format specifier for each type of variable. Use %# for object pointers. Use %d for integer types, etc. It's all documented.
#rmaddy's Answer is the gist of it. I just wanted to follow up on his comment that "It's all documented". Well, these symbols like %# and %d are called String Format Specifiers the documentation can be found at the following links.
Formatting String Objects
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/FormatStrings.html
String Format Specifiers
https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html#//apple_ref/doc/uid/TP40004265-SW1
Just telling us noobs "It's all documented" isn't very helpful because often (if you're like me) you googled to find this stackoverflow post at the top of the SEO. And taking the link in hopes of finding the original documentation!

Why are instances created using a 'literal syntax' known as 'literals'?

Something that is bothering me is why the term 'literal' is used to refer to instances of classes like NSString and NSArray. I had only seen the term used in reference to NSString and being naive I thought it had something to do with it 'literally' being a string, that is between quotation markers. Sorry if that sounds pathetic, but that was how I had been thinking about it.
Then today I learned that certain instances of NSArray can also be referred to as literal instances, i.e. an instance of the class created using a 'literal syntax'.
As #Linuxios notes, literal syntaxes are built into the language. They're broader than you think, though. A literal just means that an actual value is encoded in the source. So there are quite a few literal syntaxes in ObjC. For example:
1 - int
1.0 - double
1.0f - float
"a" - C-string
#"a" - NSString
#[] - NSArray
^{} - function
Yeah, blocks are just function literals. They are an anonymous value that is assignable to a symbol name (such as a variable or constant).
Generally speaking, literals can be stored in the text segment and be computed at compile time (rather than at run time). If I remember correctly, array literals are currently expanded into the equivalent code and evaluated at runtime, but #"..." string literals are encoded into the binary as static data (at least now they are; non-Apple versions of gcc used to encode an actual function call to construct static strings as I remember).
A literal syntax or a literal is just an object that was created using a dedicated syntax built into the language instead of using the normal syntax for object creation (whatever that is).
Here I create a literal array:
NSArray* a = #[#"Hello", #"World"];
Which is, for all intents and purposes equivalent to this:
NSArray* a = [NSArray arrayWithObjects:#"Hello", #"World", nil];
The first is called a literal because the #[] syntax is built into the language for creating arrays, in the same way that the #"..." syntax is built in for creating NSStrings.
the term 'literal' is used to refer to instances of classes
It's not referring to the instance really; after the object is created, the way it was created doesn't matter:
NSArray * thisWasCreatedWithALiteral = #[#1, #2];
NSArray * butWhoCares = thisWasCreatedWithALiteral;
The "literal" part is just the special syntax #[#1, #2], and
it ha[s] something to do with it 'literally' being a string, that is between quotation markers.
is exactly right: this is a written-out representation of the array, as opposed to one created with a constructor method like arrayWithObjects:

What does stringWithUTF8String do?

So I have done some searching around so that I could see what it was I was doing with my code, and I couldn't find any answers as to what this very one specific line of code does.
NSString* name = [NSString stringWithUTF8String:countryName];
I know what the rest does (I only had to google how to do this part), it is supposed to take my char* (countryName) and turn it into an NSString so later on I can compare it with the
isEqualToString:
thing. I would just like to know what the following is actually doing to the char, and what does the UTF8String even mean?
I have barely any Objective C programming experience so any feedback is helpful :D
you are not totally right.
this method
Returns a string created by copying the data from a given C array of UTF8-encoded bytes.
so, UTF-8 string here is just a C array of bytes.
Check the documentation here.
It doesn't do anything to the char * string. It's just the input to the method. stringWithUTF8String takes a C-style string (in UTF-8 encoding), and creates an NSString using it as a template.

Returning Integer Value in Obj-C String

I'm pretty new to Objective-C, switching over from C++, so excuse my stupid question.
I know with NSLogs and what not NSLog(#"%d is the index",i); is valid syntax. What is the reason that this: return [UIImage imageNamed:#"cover_%d.jpg", value]; isn't?
I get an error in my IDE telling me that I have too many arguments, i.e. the integer is never being used. How do I get the integer to reflect in a non-log situation?
[UIImage imageNamed:[NSString stringWithFormat:#"cover_%d.jpg", value]];
The string literal syntax doesn't support formats.
The %d (etc.) syntax is a specific convention used by particular functions like NSLog, it's not a general purpose Objective-C operation that you can expect to work with arbitrary method invocations.
Fortunately, another method that supports the %-substitutions is NSSTRing -stringWithFormat:. You use that method to create a string using the substitutions, then use that string as desired. For example:
NSString *imgName = [NSString stringWithFormat:#"cover_%d.jpg", value];
return [UIImage imageNamed:imgName];
(you could also combine these two lines into a single expression, eliminating the temporary imgName variable)

Unfamiliar C syntax in Objective-C context

I am coming to Objective-C from C# without any intermediate knowledge of C. (Yes, yes, I will need to learn C at some point and I fully intend to.) In Apple's Certificate, Key, and Trust Services Programming Guide, there is the following code:
static const UInt8 publicKeyIdentifier[] = "com.apple.sample.publickey\0";
static const UInt8 privateKeyIdentifier[] = "com.apple.sample.privatekey\0";
I have an NSString that I would like to use as an identifier here and for the life of me I can't figure out how to get that into this data structure. Searching through Google has been fruitless also. I looked at the NSString Class Reference and looked at the UTF8String and getCharacters methods but I couldn't get the product into the structure.
What's the simple, easy trick I'm missing?
Those are C strings: Arrays (not NSArrays, but C arrays) of characters. The last character is a NUL, with the numeric value 0.
“UInt8” is the CoreServices name for an unsigned octet, which (on Mac OS X) is the same as an unsigned char.
static means that the array is specific to this file (if it's in file scope) or persists across function calls (if it's inside a method or function body).
const means just what you'd guess: You cannot change the characters in these arrays.
\0 is a NUL, but including it explicitly in a "" literal as shown in those examples is redundant. A "" literal (without the #) is NUL-terminated anyway.
C doesn't specify an encoding. On Mac OS X, it's generally something ASCII-compatible, usually UTF-8.
To convert an NSString to a C-string, use UTF8String or cStringUsingEncoding:. To have the NSString extract the C string into a buffer, use getCString:maxLength:encoding:.
I think some people are missing the point here. Everyone has explained the two constant arrays that are being set up for the tags, but if you want to use an NSString, you can simply add it to the attribute dictionary as-is. You don't have to convert it to anything. For example:
NSString *publicTag = #"com.apple.sample.publickey";
NSString *privateTag = #"com.apple.sample.privatekey";
The rest of the example stays exactly the same. In this case, there is no need for the C string literals at all.
Obtaining a char* (C string) from an NSString isn't the tricky part. (BTW, I'd also suggest UTF8String, it's much simpler.) The Apple-supplied code works because it's assigning a C string literal to the static const array variables. Assigning the result of a function or method call to a const will probably not work.
I recently answered an SO question about defining a constant in Objective-C, which should help your situation. You may have to compromise by getting rid of the const modifier. If it's declared static, you at least know that nobody outside the compilation unit where it's declared can reference it, so just make sure you don't let a reference to it "escape" such that other code could modify it via a pointer, etc.
However, as #Jason points out, you may not even need to convert it to a char* at all. The sample code creates an NSData object for each of these strings. You could just do something like this within the code (replacing steps 1 and 3):
NSData* publicTag = [#"com.apple.sample.publickey" dataUsingEncoding:NSUnicodeStringEncoding];
NSData* privateTag = [#"com.apple.sample.privatekey" dataUsingEncoding:NSUnicodeStringEncoding];
That sure seems easier to me than dealing with the C arrays if you already have an NSString.
try this
NSString *newString = #"This is a test string.";
char *theString;
theString = [newString cStringWithEncoding:[NSString defaultCStringEncoding]];