How do I do the equivalent of println in Objective-C? - objective-c

In Java, I would do this:
String temp = ".";
System.out.println(temp);
How might I do that in Objective-C?

Objective-C doesn't really have its own dedicated printing function. NSLog will print what you give it along with a bunch of debugging information. For straight-up printing, the C printf() is still basically the standard. As the equivalent to your code, I'd write:
NSString *temp = #".";
printf("%s\n", [temp UTF8String]);

NSString *temp = #".";
NSLog(#"%#", temp);
NSLog format specifiers:
%# Object, calls the Object's description method
%d, %i signed int
%u unsigned int
%f float/double
%p for pointers to show the memory address
%zu value of type size_t (for sizeof(variable function)
%s C strings
\u can used for arbitrary unicode chars example:NSLog(#"\u03c0");//π

Related

Concatenating NSStrings with ints - ARC Error

I'm struggling with concatenating NSStrings and ints. In isolation the below code works great. It returns "This is a test string with an int 10"
int myInt =10;
NSString *newstring =
[NSString stringWithFormat: #"This is a test string with an int %i", myInt];
NSLog(#"%#", newstring);
However when I put the below code into my project i get an error: Implicit conversion of int to NSString is disallowed with arc."
[_mycrop setTempLeft: (#"left value %i is %i", count, [_mycrop leftValue])];
Could anybody suggest where I'm going wrong? Although im passing in 2 variables, to my mind both are essentially the same.
The code "in isolation" is very different from the second code.
You have to use stringWithFormat: in the second example too.
[_mycrop setTempLeft:[NSString stringWithFormat:#"left value %i is %i", count, [_mycrop leftValue]]];
Or with two lines but easier to understand:
NSString *tempLeft = [NSString stringWithFormat:#"left value %i is %i", count, [_mycrop leftValue]];
[_mycrop setTempLeft:tempLeft];
Some documentation: Apple String Programming Guide - Formatting String Objects

EXC_BAD_ACCESS memory issue when accessing instance variables

I'm having issues porting a Java project I worked on a while ago to Objective-C code - I get "Program received signal: "EXC_BAD_ACCESS"", on the first line in this code:
-(Point3D *) unit {
NSLog(#"%#%#", "X: ", x);
double length = [self length];
return [[Point3D alloc] initWithX:x/length andY:y/length andZ:z/length];
}
called from here:
-(id) initWithStart:(Point3D *)start andDirection:(Point3D *)dir {
if ( self = [super init] ) {
NSLog(#"%#%#", #"Direction:", [dir toString]);
printf("Trying to find unit length of direction...\n");
NSLog(#"%#", [[dir unit] toString]);
self.start = start;
self.direction = [dir unit];
}
return self;
}
Console output is:
2011-12-09 17:20:14.021 RayTracerProject[16607:407] Direction:(0,0,20)
Trying to find unit length of direction...
The toString method of the Point3D looks like this:
-(NSString *) toString {
NSNumber *xstring = [NSNumber numberWithDouble:self.x];
NSNumber *ystring = [NSNumber numberWithDouble:self.y];
NSNumber *zstring = [NSNumber numberWithDouble:self.z];
NSString * str = #"(";
str = [str stringByAppendingString:[xstring stringValue]];
str = [str stringByAppendingString:#","];
str = [str stringByAppendingString:[ystring stringValue]];
str = [str stringByAppendingString:#","];
str = [str stringByAppendingString:[zstring stringValue]];
str = [str stringByAppendingString:#")"];
return str;
}
So, from what I can see, my (Point3D *) dir is alive and well when I check what the value is using my [dir toString] call. But when I try to call [dir unit], it seems I no longer have the variables I did in the object, hence the EXC_BAD_ACCESS error.
What am I doing wrong here? I think it's something to do with the way I'm managing (or not) my memory usage, but I don't know what it is.
The NSLog in your method 'unit' should be:
NSLog(#"%# %g", #"X:", x);
Moving the space is optional, but just makes it clearer. The key issues were that you were missing the # before the "X: ", and you need to use %g rather than %# because from your other code x is a double rather than an NSObject. Equivalent—but simpler and thus better—would also be:
NSLog(#"X: %g", x);
Apple's documentation provides the definitive guide to string format specifiers and that and the surrounding documentation explain the use of format specifiers like %# (to reference an Objective C object) and %g (to reference a 64-bit floating-point number) when constructing an NSString.
It seems this line here:
NSLog(#"%#%#", "X: ", x);
should look more like this:
NSLog(#"%#%lf", #"X: ", self.x);
Note a few changes here:
From your other code, it seems you have a property named 'x'. self.x references that property. (You may or may not also have an instance variable named 'x')
Also from your other code, it seems your property 'x' is a double. So the placeholder for a double is %lf, not %#. %# is for NSObjects (and descendants)
NSString literals start with #. So #"X: " is an NSString literal. What you had is a C string.
EDIT
Well, I'm slow as usual. :) Ignore what I said and accept Duncan's answer, which was faster and now cleaner, actually.

Include a variable inside a NSString?

This works fine, we all know that:
NSString *textoutput = #"Hello";
outLabel.text = textoutput;
However, what if you want to include a variable inside that NSString statement like the following:
NSString *textoutput =#"Hello" Variable;
In C++ I know when I cout something and I wanted to include a variable all I did was soemthing like this:
cout << "Hello" << variableName << endl;
So I'm trying to accomplish that with Objective-C but I don't see how.
You can do some fancy formatting using the following function:
NSString *textoutput = [NSString stringWithFormat:#"Hello %#", variable];
Note that %# assumes that variable is an Objective-C object. If it's a C string, use %s, and if it's any other C type, check out the printf reference.
Alternatively, you can create a new string by appending a string to an existing string:
NSString *hello = #"Hello";
NSString *whatever = [hello stringByAppendingString:#", world!"];
Note that NSString is immutable -- once you assign a value, you can't change it, only derive new objects. If you are going to be appending a lot to a string, you should probably use NSMutableString instead.
I have The Cure you're looking for, Robert Smith:
if your variable is an object, use this:
NSString *textOutput = [NSString stringWithFormat:#"Hello %#", Variable];
The '%#' will only work for objects. For integers, it's '%i'.
For other types, or if you want more specificity over the string it produces, use this guide

Is the # operator in Objective-C same as the & operator in C?

New to objective C. Trying to understand pointers in Objective C.
my code
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSString *msg = #"Hello Bhai";
NSLog(#" address is %i for msg", msg);
NSLog(#" which is same address %i for Hello Bhai", #"Hello Bhai");
NSLog(#" which is different address %i for Hello mere Bhai", #"Hello mere Bhai");
NSLog(#" value is %# at the address for msg", msg);
[pool drain];
return 0;
}
output is
[Session started at 2011-04-26 16:31:11 -0400.]
2011-04-26 16:31:11.656 BasicObjC[1523:10b] address is 8240 for msg
2011-04-26 16:31:11.658 BasicObjC[1523:10b] which is same address 8240 for Hello Bhai
2011-04-26 16:31:11.659 BasicObjC[1523:10b] which is different address 8288 for Hello mere Bhai
2011-04-26 16:31:11.660 BasicObjC[1523:10b] value is Hello Bhai at the address for msg
Does this mean # in Objective C is the same as & in C
# is used to denote that string is a NSString literal so you can assign it to NSString object.
If you want to print some address then you should use %p format specifier, not %i, e.g.
NSLog(#" address is %p for msg", msg);
Does this mean # in Objective C is the same as & in C
No, in this context the '#' is used to differentiate an NSString literal from a C char array so that you can choose to use objective-c NSStrings instead of C strings.
Within a format string '%#' is used to get the string representation of an NSObject (from its "description" method) so you can output it to the console.
You are also running into a special behavior of NSString literals. Both of your #"Hello Bhai" string pointers reference the same memory address only because NSString is optimized not to create identical copies of string literals. Other objects will not necessarily behave the same way. In general you shouldn't need to be aware of this sort of optimization because should not make any difference in your use of these objects. If you correctly follow the same retain/release rules and comparisons as with any other object then you'll never notice the difference.
The at sign (#) is something completely different from the & operator. The #"…" syntax is a shorthand for creating an NSString instance from characters given in the quotes.
In general, you will see the # sign used many places in Objective-C, for syntax that is specific to that language and thus not legal in "plain" C:
#implementation
#interface
#property
#selector
#class
As noted by just about everyone else, in this specific case, #"This is a string.", it is used to indicate the start of an Objective-C string literal. It is also used as a format specifier %# to mean "object".
# was originally chosen for these purposes because it wasn't used for anything in C. The "address-of" operator & is perfectly legal in Objective-C*, because Obj-C is a superset of C.
*In fact, it gets used in Cocoa fairly often for indirect returns of values; see for example Error Handling

NSLog incorrect encoding

I've got a problem with the following code:
NSString *strValue=#"你好";
char temp[200];
strcpy(temp, [strValue UTF8String]);
printf("%s", temp);
NSLog(#"%s", temp);
in the first line of the codes, two Chinese characters are double quoted. The problem is printf function can display the Chinese characters properly, but NSLog can't.
Thanks to all. I figured out a solution for this problem. Foundation uses UTF-16 by default, so in order to use NSLog to output the c string in the example, I have to use cStringUsingEncoding to get UTF-16 c string and use %S to replace %s.
NSString *strValue=#"你好";
char temp[200];
strcpy(temp, [strValue UTF8String]);
printf("%s", temp);
strcpy(temp, [strValue cStringUsingEncoding:NSUTF16LittleEndianStringEncoding]);
NSLog(#"%S", temp);
NSLog's %s format specifier is in the system encoding, which seems to always be MacRoman and not unicode, so it can only display characters in MacRoman encoding. Your best option with NSLog is just to use the native object format specifier %# and pass the NSString directly instead of converting it to a C String. If you only have a C string and you want to use NSLog to display a message instead of printf or asl, you will have to do something like Don suggests in order to convert the string to an NSString object first.
So, all of these should display the expected string:
NSString *str = #"你好";
const char *cstr = [str UTF8String];
NSLog(#"%#", str);
printf("%s\n", cstr);
NSLog(#"%#", [NSString stringWithUTF8String:cstr]);
If you do decide to use asl, note that while it accepts strings in UTF8 format and passes the correct encoding to the syslog daemon (so it will show up properly in the console), it encodes the string for visual encoding when displaying to the terminal or logging to a file handle, so non-ASCII values will be displayed as escaped character sequences.
My guess is that NSLog assumes a different encoding for 8-bit C-strings than UTF-8, and it may be one that doesn't support Chinese characters. Awkward as it is, you might try this:
NSLog(#"%#", [NSString stringWithCString: temp encoding: NSUTF8StringEncoding]);
I know you are probably looking for an answer that will help you understand what's going on.
But this is what you could do to solve your problem right now:
NSLog(#"%#", strValue);
# define NSLogUTF8(a,b) NSLog(a,[NSString stringWithCString:[[NSString stringWithFormat:#"%#",b] cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding])
#define NSLogUTF8Ex(a,b) NSLog(a,[MLTool utf8toNString:[NSString stringWithFormat:#"%#",b]])
+(NSString*)utf8toNString:(NSString*)str{
NSString* strT= [str stringByReplacingOccurrencesOfString:#"\\U" withString:#"\\u"];
//NSString *strT = [strTemp mutableCopy];
CFStringRef transform = CFSTR("Any-Hex/Java");
CFStringTransform((__bridge CFMutableStringRef)strT, NULL, transform, YES);
return strT;
}