define String concat ios - objective-c

I have a #define hhh "uu" then I want to concat string using the following method:
NSString *str [NSString stringWithFormat#"%#%#",hhh,"ii"];
but I'm getting a compilation error.

First problem: you are missing the colon : after stringWithFormat. Second problem: you are missing the assignment operator between variable name str and initialization expression.
Third problem: the second argument to the format string #"%#%#" is a plain standard C string (a.k.a., char*), where the format string calls for an object (a.k.a., NSString). Prepend a # to the string literal:
NSString* str = [NSString stringWithFormat: #"%#%#",hhh,#"ii"];
(Edit Assumption wrong, I overlooked the define: I assume here, that hhh is an object reference, e.g., id, NSString* or something).
Since hhh is a plain string, too, you should specify %s as placeholder in the format string:
NSString* str = [NSString stringWithFormat: #"%s%#",hhh,#"ii"];
as was recommended by #sch.

Related

Using macros for string concatenation

I want to create macro that receives 2 arguments: NSString and ObjCBool and returns NSString.
I'm not familiar a lot with macros, anyway this is what I did so far:
#define fooOne(url)\
#"1111111" url
#define fooTwo(url)\
#"2222222" url
#define root(url, flag)\
if(!flag)fooOne(url)\
else fooTwo(url)
Here I have 2 problems:
1) when I call fooOne as:
NSString *url = #"zzz";
NSLog(#"%#", fooOne(url));
// expected log should be: "1111111 zzz"
I get error: Expected ')'
2) When I call root(url, flag) as:
BOOL flag = YES;
NSString *url = #"zzz";
NSLog(#"%#", root(url, flag));
// expected log should be: "2222222 zzz"
I get an error: Expected expression
please help,
Compile-time string concatenation only works with string literals. At compile time #"hello, " #"world" is combined into a new string literal #"hello, world". This doesn't work with strings contained in variables — #"blabla" url is not a valid expression, even if url contains a string literal at runtime. You would have to call your macros with the literal inside: fooOne(#"zzz"), which would expand to #"blabla" #"zzz".
If you want to combine strings at runtime, you'll need to use +[NSString stringWithFormat:], or append the strings.

objective-c - Why can I assign values to pointers?

I understand pointers work with addresses and not the data itself. This is why I need to use the address-of (&) operator below as I need to assign the address of num to the pointer and not the actual value of num (40).
int num = 40;
int *numPtr = #
Therefore i'm confused as to why I can do this.
NSString *str = #"hello";
I've created a pointer str but instead of giving it an address i'm able to assign it some data, a literal string.
I thought pointers could only hold memory addresses so why am I able to directly assign it some data?
For someone trying to get their head around pointers and objects this is very confusing.
No you are not assigning a literal string to it, # makes a NSString object with the string value hello.
In most C languages strings are just an array of char, where char is a primitive type like int like in your example.
There is a reason you put an # before string literals (when you want an NSString and not a C string) in objective-c
#"String" is basically equivalent to [NSString stringWithCString:"string"] which returns a pointer to an NSString object containing the value "string"
It is the same way 1 is a c type integer, but #1 is a NSNumber representing the value of 1. If you see an # it means "this is shorthand for creating an object". (#[] for NSArrays, #{} for NSDictionarys, #(), #123, #YES, #NO for NSNumbers, and #"" for NSString)
C does not have strings. Usually char arrays are used to represent them.
NSString *str = #"hello";
can be thought of as short hand (literal) for:
char charArray[] = "hello";
NSString *str = [[NSString alloc] initWithBytes:charArray length:sizeof(charArray) encoding:NSUTF8StringEncoding]; // disregard character encoding for this example
or
unichar bla[] = {'h', 'e', 'l', 'l', 'o'};
str = [[NSString alloc] initWithCharacters:bla length:sizeof(bla)];
So an object is created and thus you need a pointer.

Can't manipulate a string?

NSString *string = #"HELLO";
For some reason, XCode won't auto-complete methods like remove characters or append etc... If that's the case, how can I, say, remove certain characters from my string? Say I want to remove all the L's.
NSString doesn't respond to those methods. NSMutableString does, but you've declared an immutable string variable and assigned to it a string literal. Since an Objective-C #"string literal" is always immutable (an instance of NSString but not NSMutableString), there's no way those messages can be sent to the object you're using.
If you want a mutable string, try:
NSMutableString *mutableString = [[#"HELLO" mutableCopy] autorelease];
That's an immutable string literal.
Here is a great post explaining it in further details:
What's the difference between a string constant and a string literal?
As for your question on how would you change it and remove the Ls:
NSString *hello = #"HELLO";
NSString *subString = [hello stringByReplacingOccurrencesOfString:#"L" withString:#""];
NSLog(#"subString: %#", subString);
That outputs "HEO"
Either that or you can create an NSMutableString by creating a copy of the mutable string like Jonathan mentioned. In both examples, you're copying it into a non-literal string.

How to get inout to an NSString?

How to get input from an NSString as scanf ("%#", &str); doesn't work?
scanf will read into a C string and not into a NSString (as far as I know). So, to do what you're trying to do you need to first read your input into a C string (i.e. str) and then make that into an NString as follows
myString = [NSString stringWithUTF8String:str];
By the way, you don't need to pass the address of str i.e. &str if str is an array. Simply do:
scanf("%s",str);

Objective-C: initWithName:(char *)string

How would you read this in English? My concern is with the pointer. Is that pointer associated with char or with string?
Thanks in advance!
it's a pointer to char parameter named string.
So:
char * is the type of the parameter following it
string is the name of the parameter (and you should refer to this one in method body)
The part in parentheses describes the type of the parameter immediately following it—in this case, a pointer to some chars.
string is just the name of the parameter.
The type of the parameter is a pointer to a char.
The parameter is a C string, which is also named string.
[obj initWithName: "whatever"];
C strings are a '\0' terminated sequence of chars, and are declared as char *.
char *foo = "a C string";
NSString *bar = #"an objc string";