Why is my NSRange always 0? - iphone

I want to implement a delete key for my calculator app. My pseudocode for this was:
foo = length of current number
bar = length of current number-1
current number = current number with character at index (foo-bar) removed
To do this in objective-c I have tried to implement this using the NSRange function as well as the StringbyappendingString method:
- (IBAction)DelPressed {
if ([self.display.text length] >=2)
{
int len = [self.display.text length];//Length of entire display
//Add to the brainlong printing out the length of the entire display
self.brainlog.text = [NSString stringWithFormat:#"Len is %g",len];
int le = ([self.display.text length]-1);//Length of entire display - 1
NSString *lestring = [NSString stringWithFormat:#"LE is %g",le];
//Add to the brainlog printing out the length of the display -1
self.brainlog.text = [self.brainlog.text stringByAppendingString:lestring];
NSRange range = NSMakeRange(le, len);//range only includes the last character
self.display.text = [self.display.text stringByReplacingCharactersInRange:range withString:#" "];//Replace the last character with whitespace
}
The output to brainlog (ie the length of both le and len) is:
Len is -1.99164 Le is -1.99164
Hard to see, but here's an image of the number I input to the calculator using the iOS simulator:
I have tried to change the value of le (ie making it the length of the display -3 or -5 etc) and both le and len are still the same.
I have also tried to make le in reference to len:
int len = [self.display.text length];//Length of entire display
//Add to the brainlong printing out the length of the entire display
self.brainlog.text = [NSString stringWithFormat:#"Len is %g",len];
int le = len-1;
But the values of the two are still the same. How can I use NSRange to delete the last character of the display?
Edit: Using Dustin's fix, I now have reduced a rather lengthy function into 6 lines of code:
-(IBAction)DelPressed{
if ([self.display.text length] >=2)
{
self.display.text = [self.display.text substringToIndes:[self.display.text length] -1];
}
}

Use substring instead; it's much better if all you want to do is remove the last character.
More specifically, substringToIndex(/*length-1*/)
Check this reference out if you need to do other things with strings

Related

get random string with limit 10 maximum ios?

am generating random string it contains alpha numberic values. The thing is i need to set exactly 10 digits to store in a particular string sometime i getting 10 digits exactly but most of the time i am getting 4,5,7, or even 1 character values :
here my sample code :
NSString *alphabet = #"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXZY0123456789";
NSMutableString *s = [NSMutableString stringWithCapacity:10];
for (NSUInteger i = 0; i < 10; i++) {
u_int32_t r = arc4random() % [alphabet length];
unichar c = [alphabet characterAtIndex:r];
[s appendFormat:#"%C", c];
NSLog(#"%#",s);
}
my nslog :
y
yC
yCD
yCDC
yCDCd
yCDCdP
yCDCdP1
yCDCdP1F
yCDCdP1Fg
yCDCdP1Fgq
There's nothing wrong with the code.
Just, put NSLog(#"%#",s); right out of the for loop.
You have put your NSLog inside the for loop. That might make you think it's wrong. Take
NSLog(#"%#",s);
out of the loop.

Convert NSNumber to hex string with 16 digits

I have to convert an NSNumber to a hex string like follows:
return [NSString stringWithFormat:#"%llX", self.unsignedLongLongValue];
Unfortunately, this will sometimes give me string like 93728A166D1A287 where they should be 093728A166D1A287, depending on the number.
Hint: the leading 0.
I've also tried it with:
return [NSString stringWithFormat:#"%16.llX", self.unsignedLongLongValue];
without success.
I could do something like this, but that just sucks:
- (NSString *)hexValue {
NSString *hex = [NSString stringWithFormat:#"%llX", self.unsignedLongLongValue];
NSUInteger digitsLeft = 16 - hex.length;
if (digitsLeft > 0) {
NSMutableString *zeros = [[NSMutableString alloc] init];
for (int i = 0; i < digitsLeft; i++) [zeros appendString:#"0"];
hex = [zeros stringByAppendingString:hex];
}
return hex;
}
So finally my question, is there a way to enforce the string to be 16 characters?
If you need to zero-pad your hex numbers, use zero in front of the format specifier, like this:
return [NSString stringWithFormat:#"%016llX", self.unsignedLongLongValue];
This should take care of formatting your number with 16 digits, regardless of how many "meaningful" digits the number has.
Here is a demo of this format string in plain C (this part is shared between the two languages).
Use:
return [NSString stringWithFormat:#"%016llX", self.unsignedLongLongValue];
Which sets leading 0 and the length of the output string.

Finding multiple numerations of a character in UITextView

I am a UITextView where I am trying to find the # character. The text view might have multiple #s, so I was wondering, how can I find the nth # character?
Currently, I have: NSRange range = [textViewText rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:#"#"]];. This only finds the first # instance. How can I find subsequent ones?
You could try doing something like splitting up the text based on #"#" and then you know where the components are split, thats where the # should appear. This way you can easily find the nth #
If I understand you question correctly, a regular expression would solve you problem.
RegEx has a bit of a learning curve but it comes in handy very often.
http://www.regular-expressions.info/
is a very good starting point for regular expressions in general
http://remarkablepixels.com/blog/2011/1/13/regular-expressions-on-ios-nsregularexpression.html
A tutorial about regular expression in iOS
http://reggyapp.com/
Reggy is an osx app in which you can test your RegEx on actual text.
What do you want to do once you've located the nth #?
Here's some sample code that sketches a solution. Not compiled or checked for bugs!
int targetItem = 3; // we find the 3rd item
NSString *workingStr = #"your#string#containing#stuff";
int foundAtLocation = -1;
for (int idx = 0; idx < targetItem; idx++) {
NSRange range = [workingStr rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:#"#"]];
if (range.location < 0) {
// not found, give up
foundAtLocation = -1;
break;
}
workingStr = [workingStr substringFromIndex:range.location];
foundAtLocation += range.location;
}
if (foundAtLocation >= 0) {
NSLog(#" I found the %d occurence of # at character index %d", targetItem, foundAtLocation);
}
else {
NSLog(#" Not found");
}

iPhone iOS how to count number of case-insensitive occurrences of a word within a string?

I'm looking for a way to search an arbitrary long string (10000 characters) and find the number of times a specific keyword is repeated in the string. How can this be done?
I have this method, that pretty much counts the number of fragments left after the string is split around keywords, but it is not case insensitive.
-(void)countKeywords
{
NSArray* components = [self.salesCopy componentsSeparatedByString:#"search term"];
NSLog(#"search term number found: %i",components.count);
}
What's a better way to count the number of keywords within a string?
Splitting the string, counting parts, and throwing them away is not efficient. Searching for substring repeatedly without creating new objects would definitely be more efficient. Since the string is relatively long, you may benefit from implementing an advanced string search algorithm, for example Knuth-Morris-Pratt, to significantly decrease your search time.
Here is an implementation that should be faster than your splitting code:
NSString *str = #"Hello sun, hello bird, hello my lady! Hello breakfast, May I buy you again tomorrow?";
NSRange r = NSMakeRange(0, str.length);
int count = 0;
for (;;) {
r = [str rangeOfString:#"hello" options:NSCaseInsensitiveSearch range:r];
if (r.location == NSNotFound) {
break;
}
count++;
r.location++;
r.length = str.length - r.location;
}
NSLog(#"%d", count);
Just create copies of both self.salesCopy and the searchTerm, set the copies to lower case via [NSString lowercaseString], then perform your code, and you'll have the count
-(void)countKeywords
{
NSString *lowerCaseSalesCopy = [self.salesCopy lowercaseString];
NSString *lowerCaseSearchTerm = [searchTerm lowercaseString];
NSArray* components = [lowerCaseSalesCopy componentsSeparatedByString:lowerCaseSearchTerm];
NSLog(#"search term number found: %i",components.count);
}
I am not 100% sure that could help you, but may do some of the job you need (if not all):
NSRange ran = [yourString rangeOfString:wordToLookFor options:NSCaseInsensitiveSearch];
And look at
ran.length
ran.location
ran.location will provide you the location within the string of the first occurrence. You could then cut the string after this occurrence, and run this again until the end of the string.

Checking if a nsstring matches another string

Suppose I have a string "167282". How can I check if the string contains "128"? Is there any provision to know the percentage of the 2nd string that matches the first string? (If all the characters of the 2nd string are present in the first string or not.) Please help and thanx in advance.
Use the following:
NSString *compareString = #"128";
NSCharacterSet *compareCharSet = [NSCharacterSet characterSetWithCharactersInString:#"167282"];
NSUInteger strLen = [compareString length];
NSUInteger matchingCount = 0;
for (NSUInteger i = 0; i < strLen; ++i) {
if ([compareCharSet characterIsMember:[compareString characterAtIndex:i]])
++matchingCount;
}
float percentMatching = matchingCount/(float)strLen;
Where matchingCount will be the number of characters in compareString that match a character in #"167282" and percentMatching will be the percent of total characters in compareString that match. This is, as best as I can tell, what you intended with your question - the concept of a percent match wouldn't make any sense otherwise.
You can use NSString's rangeOfString method to find out whether a string contains another string, as suggested by the answers to this question on the Apple Mailing Lists.
if ([#"167282" rangeOfString:#"128"].location != NSNotFound) {
NSLog(#"String contains '128'.");
}
else {
NSLog(#"String doesn't contain '128'.");
}
You could always use the NSString method rangeOfString: to check whether or not your original string contains your desired substring. This method will return an NSRange with the location of your substring within the original string:
[#"12345" rangeOfString:#"123"]; // Gives range {0, 3}
[#"12345" rangeOfString:#"345"]; // Gives range {2, 3}
[#"12345" rangeOfString:#"678"]; // Gives range {NSNotFound, 0}
This only works if the substring is entirely contained within the original string.
As for the "amount correct," you can use the length property of the returned range, along with the length of the original string, to see what part of the original string is comprised by the substring. For example:
NSRange r = [#"1234" rangeOfString:#"1"]; // Range {0, 1}
float portion = (float)r.length / (float)[#"1234" length]; // Gives 0.25f
Keep in mind this will fall apart if the substring is repeated - checking for #"1" as the substring of #"111" will give only the first occurrence, meaning it'll claim the string is "33% correct" by this method. Depending on your intended use, this may or may not be what you want.