iOS stringWithFormat shorthand WITH nil check - nsstring

I am trying to make a shorthand for [NSString stringWithFormat]:
How can I turn this (working):
#define fstring(s, ...) [NSString stringWithFormat:(s), ##__VA_ARGS__]
into this (with a check for nil value)
#define fstring(s, ...) [NSString stringWithFormat:(s), ##__VA_ARGS__ (__VA_ARGS__ ?:#"")]
Something like:
NSString *fullName = [NSString stringWithFormat:#"%#", contact.firstName ?: #""]
I have tried different shorthand combinations without luck... anybody got a better idea?
EDIT - Solution found
#define fstring(s, ...) [NSString stringWithFormat:(s), ##__VA_ARGS__ ?:#""]

Solution is the following:
#define fstring(s, ...) [NSString stringWithFormat:(s), ##__VA_ARGS__ ?:#""]
and if you want with empty string if null:
#define fstringOrEmpty(...) __VA_ARGS__ ? : #""

Related

Don't laugh, but what on earth am i missing?

OK, I probably have no business trying to learn an OOP and I'm having trouble with the simplest little first program. I am getting a message that my implementation is incomplete (I commented the line that is giving 4 errors below). What is wrong? It wants a type specifier among other things, but don't I give it one with NSString? I do notice that NSString doesn't change color to a green type color in XCODE in the implementation like it does in the interface.
ALSO, why do we need to declare the method in the interface and type the exact same thing in the implementation? that is, why the need to type the startDrinking: (NSString*) newBeverage in both?
#import <Foundation/Foundation.h>
#interface Drinks : NSObject {
NSString *beverage;
}
- (void) startDrinking: (NSString*) newBeverage; // setter
- (void) printDrink;
#end
#implementation Drinks
{
//THIS NEXT LINE IS WHERE I GET 4 ERRORS
- (void) startDrinking: (NSString *) newBeverage {
beverage = [[NSString alloc]initwithString:newBeverage]
}
-(void) printDrink {
NSLog(#"How is your", beverage);
}
}
#end
int main (int argc, const char * argv[]) {
Drinks *beverage = [[Drinks alloc] init];
[beverage startDrinking:#"Lemonade"];
return 0;
}
Your question is too chatty.
You missed a semi-colon in line beverage = [[NSString alloc]initwithString:newBeverage]
The line should be :
beverage = newBeverage;
and the NSLog line should be:
NSLog(#"How is your %#", beverage);
and for the declaration of method signature in header, it is followed by C and C++ . You can think of, the Compiler needs to know which functions are available first.
Your mistake is the { right below #implementation Drinks.
That's why the alignment is messed up too.
In general, if you can't find an error on the line it is reported on, just check any extraneous or missing parenthesis, brackets or braces.
The weird alignment is another clue to this.
Hope this helps. Also, like some other said, it helps if your subject is more meaningful. Not just for yourself, but also for any others that might be having a similar problem

How to plus "NSString" in IOS programming?

How to plus NSString?
Example:
NSString *a=#"hello";
NSString *b=#"world";
NSString *s=#"";
I want:
s = "helloworld";
Thank for helping.
Please use below code.
NSString *s= [NSString stringWithFormat:#"%#%#", a, b];
What you are talking about is concatenating. And you need to use:
NSString *a = #"This ";
NSString *b = #"is a string";
NSString *c= [NSString stringWithFormat:#"%#%#", a, b];
Check out: objective-c strings a guide for beginners for a full list.
You can also use stringByAppendingString: like so -
NSString *completeString = [a stringByAppendingString:b];
NSString *a=#"hello";
NSString *b=#"world";
NSString *s=[NSString stringWithFormat:#"%#%#", a, b];
NSString *completeString = [a stringByAppendingString:b];
This function is Good and Easy...

NSString stringWithUTF8String return null on device, but ok on simulator

I have a really weird problem. Basically just convert a char to nsstring and store them in an nsmutable array.
But the code runs ok on simulator, but crash on device.
Here is the crash code,
char t = 'A' + i;
NSString* alphabetString = [NSString stringWithUTF8String:&t]; //substringToIndex:1];
[tempArray addObject:alphabetString];
Basically the stringWithUTF8String will return NULL on device, but return valid value on simulator.
The device is an iPhone 4s.
I did not see any notification of changes on NSString stringwithutf8string on iOS5 release.
Thanks.
The address of a single char is not a C-style string. You need to ensure it's null terminated with something like:
char t = 'A' + i;
char s[2]; s[0] = t; s[1] = '\0';
NSString* alphabetString = [NSString stringWithUTF8String:s];
From the docpage:
Parameters
bytes : A NULL-terminated C array of bytes in UTF8 encoding.
You can't pass the address of a single char value to -stringWithUTF8String. That function is expecting a null-terminated string, and you're not passing it one. This results in undefined behavior: anything at all could happen. It might appear to succeed, it might fail benignly, or it might erase your file system. But more likely, it will just crash your program.
You should create a two-character array that's null-terminated instead:
char t[2] = {'A' + i, 0}; // Two-character null-terminated array
NSString* alphabetString = [NSString stringWithUTF8String:t];
Alternatively, you can also use -stringWithFormat: with the %c format specifier to get a string containing a single character:
NSString* alphabetString = [NSString stringWithFormat:#"%c", 'A' + i];

Convert NSMutableArray to String problem

I have got a little problem.
I would like to save an array to a textfile with this code:
for(int aa = 0; aa <= [lines2 count]; aa++) {
content = [[NSString alloc] initWithFormat:#"%#;%#", content, [lines2 objectAtIndex:aa]];
}
NSString *filePath = [[NSBundle mainBundle]pathForResource:#"cart" ofType:#"txt"]; //meine Zeile
[content writeToFile:filePath atomically:NO encoding:NSStringEncodingConversionAllowLossy error:nil];
But it crashes my app. Can anybody give me an easy example, how to convert an NSMutable Array from
One
Two
Three
to an NSString like
One;Two;Three
Hope somebody can help me... :(
You should be able to do the concatenation using somewhat simpler code as below:
NSMutableString* content = [NSMutableString string];
for (int aa=0; aa < [lines2 count]; aa++){
[content appendString:[NSString stringWithFormat:#"%# ",[lines2 objectAtIndex:aa]]];
}
or, You could use componentsJoinedByString.
Maybe less, instead of less_or_equal?
for(int aa = 0; aa < [lines2 count]; aa++)

Problem with stringByTrimmingCharactersInSet:

I'm doing a very simple trimming from a string. Basically it goes like this:
int main (int argc, const char * argv[]) {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
s = [s stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"%#",s);
[pool drain];
return 0;
}
No matter how many times I check, I can't find a mistake on the code. But the compiler keeps returning:
Running…
2009-12-30 08:49:22.086 Untitled[34904:a0f] Some other string
It doesn't trim the string at all. Is there a mistake in my code, because I can't believe something this simple doesn't work. Thanks!
Edit:
I think I've figured my mistake. stringByTrimmingCharactersInSet only trims the string from the leftmost and rightmost ends of a string. Can anybody confirm this?
You are correct - with your code stingByTrimmingCharactersInSet will trim the left and right whitespace but leave internal whitespace alone.
Note that there's also a memory leak in your code sample:
NSString *s = [[NSString alloc] initWithString:#"Some other string"];
This will leak when you re-assign to s in the next line.

Resources