what is the sign # for ?
I thought NSLog("X =%i and Y= %i", _x, _y); without # is meaningful enough.
- (void) print
{
NSLog(#"X =%i and Y= %i", _x, _y);
}
Other than all the great answers from the link #giorashc gave in his comment, basically #"stuff" is the way to create an NSString object in cocoa. Even the dedicated method of NSString for creating a string asks for an NSString object.
[NSString stringWithFormat:..]
The # symbol is also used as syntax-shortcuts to create NSNumber, NSArray, NSDictioary... e.g. This: [NSArray arrayWithObjects:obj1,obj2, nil] is equel to: #[obj1, obj2]
In Obj C the # sign is required to indicate the beginning of a string constant.
NSString *txt = #"sample";
You're specifying a literal format string, so there you are...
In objective-c using characters without '#' token denotes C type (char *) or (const char *). Adding prefix '#' token denotes an NSString literal.
Related
I am attempting to use scanf to assign a value to an NSString, as per the answers to this question by Omar. This is the code, taken straight from progrmr's answer:
char word[40];
int nChars = scanf("%39s", word); // read up to 39 chars (leave room for NUL)
NSString* word2 = [NSString stringWithBytes:word
length:nChars
encoding:NSUTF8StringEncoding];
However, I'm getting an error on the last line that makes absolutely no sense to me:
No known class method for selector 'stringWithBytes:length:encoding:'
What in the world could be causing this error?
And yes, I do have #import <Foundation/Foundation.h> at the top of the file.
NSString does not have a stringWithBytes:length:encoding: class method, but you can use
NSString* word2 = [[NSString alloc] initWithBytes:word
length:nChars
encoding:NSUTF8StringEncoding];
Note however, that scanf() returns the number of scanned items and
not the number of scanned characters. So nChars will contain 1 and not the string length, so you should set nChars = strlen(word) instead.
A simpler alternative is (as also mentioned in one answer to the linked question)
NSString* word2 = [NSString stringWithUTF8String:word];
NSString does not respond to the selector stringWithBytes:length:encoding:. You probably wanted initWithBytes:length:encoding:.
Story in short: you might want to consider a const char C-string suitable initializer for your NSString object. Also, allocate memory before sending any initializer message to the NSString object. I would expect something like:
char word[40];
int nChars = scanf("%39s", word);
NSString *word2 = [[NSString alloc] initWithCString:word encoding:NSASCIIStringEncoding];
Note that initWithCString per design only supports properly null '\0' terminated 8-bit character arrays. For unterminated bytes arrays you have initWithBytes:length:encoding: instead.
For Unicode characters you could consider initWithCharactersNoCopy:length:freeWhenDone:.
I need my user to enter numbers to type his telephone number.The user can only enter 8 numbers(for eg. XXXXXXXX). I need to change the phone number to be in the format XX-XX-XXXX.
This is what I have tried:
[tfDID.text insertString:#"-" atIndex:2];
[tfDID.text insertString:#"-" atIndex:5];
But it is returning me an error saying:
No Visible #interface for 'NSString' declares the selector 'insertString:atIndex:'
Need some guidance on this. Sorry if this is a stupid question.
No Visible #interface for 'NSString' declares the selector 'insertString:atIndex:'
As you are trying to mutate the textbox's value, which returns you NSString.
NSString object can not be mutated, so convert it into a mutable string then manupulate it.
Make your string NSMutableString.
As,
NSMutableString *tfDIDString=[NSMutableString stringWithString:tfDID.text];
[tfDIDString insertString:#"-" atIndex:2];
[tfDIDString insertString:#"-" atIndex:5];
[UITextField text] is NSString, you need to declare local variable of NSMutableString and perform insertString operations on it
Hope it helps you
Implement <UITextFieldDelegate> and then do:
-(void)textFieldDidChange:(UITextField*)textField
{
if( textField.text.length == 2 || textField.text.length == 5 ){
textField.text = [textField.text stringByAppendingString:#"-"];
}
}
Completely agree with the answer suggesting making it a mutable string.
Just to play devils advocate you could do:
NSString *partOne = [NSString stringWithRange:NSMakeRange(0,2)];
NSString *partTwo = [NSString stringWithRange:NSMakeRange(2,2)];
NSString *partThree = [NSString stringWithRange:NSMakeRange(4,4)];
NSString *formattedNumber = [NSString stringWithFormat:#"%#-%#-%#",partOne,partTwo,partThree];
I've written it out longhand but you could compress the string declarations for the parts in to the stringWithFormat call if you don't mind nesting and sacrifcing a bit of readability.
I'm trying to loop through a NSString, character by character, but I'm getting a EXC_BAD_ACCESS error. Do you have an idea how to do this right? I've been googling for hours now but can't figure it out.
Here is my code (.m):
self.textLength = [self.text length];
for (int position=0; position < self.textLength; position++) {
NSLog(#"%#", [self.text characterAtIndex:position]);
if ([[self.text characterAtIndex:position] isEqualToString:#"."]){
NSLog(#"it's a .");
}
}
Thanks a lot!
Characters are not object. characterAtIndex returns unichar, which is actually an integer type unsigned short. You need to use %C instead of %# in NSLog. Also character is not a NSString, so you can't send it isEqualToString. You need to use ch == '.' to compare ch against '.'.
unichar ch = [self.text characterAtIndex:position];
NSLog(#"%C", ch);
if (ch == '.') {} // single quotes around dot, not double quotes
Note that, 'a' is character, "a" is C string and #"a" is NSString. They all are different types.
When you are using %# with unichar ch in NSLog, it is trying to print an object from memory location ch which is invalid. Thus you are getting a EXC_BAD_ACCESS.
characterAtIndex: returns a unichar, so you should use NSLog(#"%C", ...) instead of #"%#".
You also cannot use isEqualToString for a unichar, just use == '.' is fine.
If you want to find the position of all '.'s, you can use rangeOfString. Refer to:
String Programming Guide: Searching, Comparing, and Sorting Strings
Position of a character in a NSString or NSMutableString
characterAtIndex: returns a unichar, which is declared as typedef unsigned short unichar; The format specifier you are using in your calls to NSLog are incorrect, you could just do NSLog(#"%u",[self.text characterAtIndex:position]); or NSLog(#"%C",[self.text characterAtIndex:position]); if you want the actual character to print out.
Also, as a result of unichar being defined the way that it is, it's not a string, so you cannot compare it to other strings. Try something like:
unichar textCharacter = '.';
if ([self.text characterAtPosition:position] == testCharacter) {
// do stuff
}
If you want to find the location of a character in a string you can use this:
NSUInteger position = [text rangeOfString:#"."].location;
if the character or text is not found you will get a NSNotFound:
if(position==NSNotFound)
NSLog(#"text not found!");
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.
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